SFAPIclient/Requests/IDNAEncoder.php
public static function punycode_encode($input) {
		$output = '';
#		let n = initial_n
		$n = self::BOOTSTRAP_INITIAL_N;
#		let delta = 0
		$delta = 0;
#		let bias = initial_bias
		$bias = self::BOOTSTRAP_INITIAL_BIAS;
#		let h = b = the number of basic code points in the input
		$h = $b = 0; // see loop
#		copy them to the output in order
		$codepoints = self::utf8_to_codepoints($input);

		foreach ($codepoints as $char) {
			if ($char < 128) {
				// Character is valid ASCII
				// TODO: this should also check if it's valid for a URL
				$output .= chr($char);
				$h++;
			}
			// Check if the character is non-ASCII, but below initial n
			// This never occurs for Punycode, so ignore in coverage
			// @codeCoverageIgnoreStart
			elseif ($char < $n) {
				throw new Requests_Exception('Invalid character', 'idna.character_outside_domain', $char);
			}
			// @codeCoverageIgnoreEnd
			else {
				$extended[$char] = true;
			}
		}
		$extended = array_keys($extended);
		sort($extended);
		$b = $h;
#		[copy them] followed by a delimiter if b > 0
		if (strlen($output) > 0) {
			$output .= '-';
		}
#		{if the input contains a non-basic code point < n then fail}
#		while h < length(input) do begin
		while ($h < count($codepoints)) {
#			let m = the minimum code point >= n in the input
			$m = array_shift($extended);
			//printf('next code point to insert is %s' . PHP_EOL, dechex($m));
#			let delta = delta + (m - n) * (h + 1), fail on overflow
			$delta += ($m - $n) * ($h + 1);
#			let n = m
			$n = $m;
#			for each code point c in the input (in order) do begin
			for ($num = 0; $num < count($codepoints); $num++) {
				$c = $codepoints[$num];
#				if c < n then increment delta, fail on overflow
				if ($c < $n) {
					$delta++;
				}
#				if c == n then begin
				elseif ($c === $n) {
#					let q = delta
					$q = $delta;
#					for k = base to infinity in steps of base do begin
					for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) {
#						let t = tmin if k <= bias {+ tmin}, or
#								tmax if k >= bias + tmax, or k - bias otherwise
						if ($k <= ($bias + self::BOOTSTRAP_TMIN)) {
							$t = self::BOOTSTRAP_TMIN;
						}
						elseif ($k >= ($bias + self::BOOTSTRAP_TMAX)) {
							$t = self::BOOTSTRAP_TMAX;
						}
						else {
							$t = $k - $bias;
						}
#						if q < t then break
						if ($q < $t) {
							break;
						}
#						output the code point for digit t + ((q - t) mod (base - t))
						$digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
						//printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($digit));
						$output .= self::digit_to_char($digit);
#						let q = (q - t) div (base - t)
						$q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
#					end
					}
#					output the code point for digit q
					$output .= self::digit_to_char($q);
					//printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($q));
#					let bias = adapt(delta, h + 1, test h equals b?)
					$bias = self::adapt($delta, $h + 1, $h === $b);
					//printf('bias becomes %d' . PHP_EOL, $bias);
#					let delta = 0
					$delta = 0;
#					increment h
					$h++;
#				end
				}
#			end
			}
#			increment delta and n
			$delta++;
			$n++;
#		end
		}

		return $output;
	}
public static function punycode_encode($input) {
		$output = '';
#		let n = initial_n
		$n = self::BOOTSTRAP_INITIAL_N;
#		let delta = 0
		$delta = 0;
#		let bias = initial_bias
		$bias = self::BOOTSTRAP_INITIAL_BIAS;
#		let h = b = the number of basic code points in the input
		$h = $b = 0; // see loop
#		copy them to the output in order
		$codepoints = self::utf8_to_codepoints($input);

		foreach ($codepoints as $char) {
			if ($char < 128) {
				// Character is valid ASCII
				// TODO: this should also check if it's valid for a URL
				$output .= chr($char);
				$h++;
			}
			// Check if the character is non-ASCII, but below initial n
			// This never occurs for Punycode, so ignore in coverage
			// @codeCoverageIgnoreStart
			elseif ($char < $n) {
				throw new Requests_Exception('Invalid character', 'idna.character_outside_domain', $char);
			}
			// @codeCoverageIgnoreEnd
			else {
				$extended[$char] = true;
			}
		}
		$extended = array_keys($extended);
		sort($extended);
		$b = $h;
#		[copy them] followed by a delimiter if b > 0
		if (strlen($output) > 0) {
			$output .= '-';
		}
#		{if the input contains a non-basic code point < n then fail}
#		while h < length(input) do begin
		while ($h < count($codepoints)) {
#			let m = the minimum code point >= n in the input
			$m = array_shift($extended);
			//printf('next code point to insert is %s' . PHP_EOL, dechex($m));
#			let delta = delta + (m - n) * (h + 1), fail on overflow
			$delta += ($m - $n) * ($h + 1);
#			let n = m
			$n = $m;
#			for each code point c in the input (in order) do begin
			for ($num = 0; $num < count($codepoints); $num++) {
				$c = $codepoints[$num];
#				if c < n then increment delta, fail on overflow
				if ($c < $n) {
					$delta++;
				}
#				if c == n then begin
				elseif ($c === $n) {
#					let q = delta
					$q = $delta;
#					for k = base to infinity in steps of base do begin
					for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) {
#						let t = tmin if k <= bias {+ tmin}, or
#								tmax if k >= bias + tmax, or k - bias otherwise
						if ($k <= ($bias + self::BOOTSTRAP_TMIN)) {
							$t = self::BOOTSTRAP_TMIN;
						}
						elseif ($k >= ($bias + self::BOOTSTRAP_TMAX)) {
							$t = self::BOOTSTRAP_TMAX;
						}
						else {
							$t = $k - $bias;
						}
#						if q < t then break
						if ($q < $t) {
							break;
						}
#						output the code point for digit t + ((q - t) mod (base - t))
						$digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
						//printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($digit));
						$output .= self::digit_to_char($digit);
#						let q = (q - t) div (base - t)
						$q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
#					end
					}
#					output the code point for digit q
					$output .= self::digit_to_char($q);
					//printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($q));
#					let bias = adapt(delta, h + 1, test h equals b?)
					$bias = self::adapt($delta, $h + 1, $h === $b);
					//printf('bias becomes %d' . PHP_EOL, $bias);
#					let delta = 0
					$delta = 0;
#					increment h
					$h++;
#				end
				}
#			end
			}
#			increment delta and n
			$delta++;
			$n++;
#		end
		}

		return $output;
	}
public static function punycode_encode ( $ input ) { $ output = '' ; #		let n = initial_n $ n = self :: BOOTSTRAP_INITIAL_N ; #		let delta = 0 $ delta = 0 ; #		let bias = initial_bias $ bias = self :: BOOTSTRAP_INITIAL_BIAS ; #		let h = b = the number of basic code points in the input $ h = $ b = 0 ; // see loop #		copy them to the output in order $ codepoints = self :: utf8_to_codepoints ( $ input ) ; foreach ( $ codepoints as $ char ) { if ( $ char < 128 ) { // Character is valid ASCII // TODO: this should also check if it's valid for a URL $ output .= chr ( $ char ) ; $ h ++ ; } // Check if the character is non-ASCII, but below initial n // This never occurs for Punycode, so ignore in coverage // @codeCoverageIgnoreStart elseif ( $ char < $ n ) { throw new Requests_Exception ( 'Invalid character' , 'idna.character_outside_domain' , $ char ) ; } // @codeCoverageIgnoreEnd else { $ extended [ $ char ] = true ; } } $ extended = array_keys ( $ extended ) ; sort ( $ extended ) ; $ b = $ h ; #		[copy them] followed by a delimiter if b > 0 if ( strlen ( $ output ) > 0 ) { $ output .= '-' ; } #		{if the input contains a non-basic code point < n then fail} #		while h < length(input) do begin while ( $ h < count ( $ codepoints ) ) { #			let m = the minimum code point >= n in the input $ m = array_shift ( $ extended ) ; //printf('next code point to insert is %s' . PHP_EOL, dechex($m)); #			let delta = delta + (m - n) * (h + 1), fail on overflow $ delta += ( $ m - $ n ) * ( $ h + 1 ) ; #			let n = m $ n = $ m ; #			for each code point c in the input (in order) do begin for ( $ num = 0 ; $ num < count ( $ codepoints ) ; $ num ++ ) { $ c = $ codepoints [ $ num ] ; #				if c < n then increment delta, fail on overflow if ( $ c < $ n ) { $ delta ++ ; } #				if c == n then begin elseif ( $ c === $ n ) { #					let q = delta $ q = $ delta ; #					for k = base to infinity in steps of base do begin for ( $ k = self :: BOOTSTRAP_BASE ; ; $ k += self :: BOOTSTRAP_BASE ) { #						let t = tmin if k <= bias {+ tmin}, or #								tmax if k >= bias + tmax, or k - bias otherwise if ( $ k <= ( $ bias + self :: BOOTSTRAP_TMIN ) ) { $ t = self :: BOOTSTRAP_TMIN ; } elseif ( $ k >= ( $ bias + self :: BOOTSTRAP_TMAX ) ) { $ t = self :: BOOTSTRAP_TMAX ; } else { $ t = $ k - $ bias ; } #						if q < t then break if ( $ q < $ t ) { break ; } #						output the code point for digit t + ((q - t) mod (base - t)) $ digit = $ t + ( ( $ q - $ t ) % ( self :: BOOTSTRAP_BASE - $ t ) ) ; //printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($digit)); $ output .= self :: digit_to_char ( $ digit ) ; #						let q = (q - t) div (base - t) $ q = floor ( ( $ q - $ t ) / ( self :: BOOTSTRAP_BASE - $ t ) ) ; #					end } #					output the code point for digit q $ output .= self :: digit_to_char ( $ q ) ; //printf('needed delta is %d, encodes as "%s"' . PHP_EOL, $delta, self::digit_to_char($q)); #					let bias = adapt(delta, h + 1, test h equals b?) $ bias = self :: adapt ( $ delta , $ h + 1 , $ h === $ b ) ; //printf('bias becomes %d' . PHP_EOL, $bias); #					let delta = 0 $ delta = 0 ; #					increment h $ h ++ ; #				end } #			end } #			increment delta and n $ delta ++ ; $ n ++ ; #		end } return $ output ; }
RFC3492-compliant encoder

@internal Pseudo-code from Section 6.3 is commented with "#" next to relevant code
@throws Requests_Exception On character outside of the domain (never happens with Punycode) (`idna.character_outside_domain`)

@param string $input UTF-8 encoded string to encode
@return string Punycode-encoded string
RFC3492 - compliant encoder