Title: IdnaEncoder::punycode_encode
Published: March 29, 2023
Last modified: November 8, 2023

---

# IdnaEncoder::punycode_encode( string $input ): string

## In this article

 * [Parameters](https://developer.wordpress.org/reference/classes/wporg-requests-idnaencoder/punycode_encode/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/classes/wporg-requests-idnaencoder/punycode_encode/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/classes/wporg-requests-idnaencoder/punycode_encode/?output_format=md#source)

[ Back to top](https://developer.wordpress.org/reference/classes/wporg-requests-idnaencoder/punycode_encode/?output_format=md#wp--skip-link--target)

RFC3492-compliant encoder

## 󠀁[Parameters](https://developer.wordpress.org/reference/classes/wporg-requests-idnaencoder/punycode_encode/?output_format=md#parameters)󠁿

 `$input`stringrequired

UTF-8 encoded string to encode

## 󠀁[Return](https://developer.wordpress.org/reference/classes/wporg-requests-idnaencoder/punycode_encode/?output_format=md#return)󠁿

 string Punycode-encoded string

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wporg-requests-idnaencoder/punycode_encode/?output_format=md#source)󠁿

    ```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 = 0;
    	$b = 0; // see loop
    	// copy them to the output in order
    	$codepoints = self::utf8_to_codepoints($input);
    	$extended   = [];

    	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 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
    	$codepointcount = count($codepoints);
    	while ($h < $codepointcount) {
    		// 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 < $codepointcount; $num++) {
    			$c = $codepoints[$num];
    			// if c < n then increment delta, fail on overflow
    			if ($c < $n) {
    				$delta++;
    			} elseif ($c === $n) { // if c == n then begin
    				// 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   = (int) ($t + (($q - $t) % (self::BOOTSTRAP_BASE - $t)));
    					$output .= self::digit_to_char($digit);
    					// let q = (q - t) div (base - t)
    					$q = (int) floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
    				} // end
    				// output the code point for digit q
    				$output .= self::digit_to_char($q);
    				// let bias = adapt(delta, h + 1, test h equals b?)
    				$bias = self::adapt($delta, $h + 1, $h === $b);
    				// let delta = 0
    				$delta = 0;
    				// increment h
    				$h++;
    			} // end
    		} // end
    		// increment delta and n
    		$delta++;
    		$n++;
    	} // end

    	return $output;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/requests/src/idnaencoder.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.0/src/wp-includes/Requests/src/IdnaEncoder.php#L253)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.0/src/wp-includes/Requests/src/IdnaEncoder.php#L253-L353)

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwporg-requests-idnaencoder%2Fpunycode_encode%2F)
before being able to contribute a note or feedback.