How to convert a country code to an emoji flag

PHP Emoji Flag
Under ISO 3166-1 alpha-2, country codes are defined as a two-letter string.

Some examples are extremely obvious: GB for Great Britain, US for the United States, HK for Hong Kong and so on.

Others may be derived from their native language country names, e.g. CH for Switzerland, DE for Germany and KH for Cambodia.

These two-letter country codes usually coincide with their top-level domains, e.g. SE/.se, NO/.no, etc.
There is one well-known exception: the country code GB has top-level domain .uk because .gb is now defunct.

The Unicode Consortium publish the list of emoji flags here:
unicode.org

Each flag consists of two encoded HTML characters (in the form &#x[hex];) which are interpreted by the browser and displayed as a single flag emoji.

Some browsers, such as Firefox currently do not display the flag, but rather show equivalent letters, e.g. "GB" for the equivalent hex-coded characters.

So, we come to the main point...

How do we convert a two-letter country code to an emoji flag?




  1. Convert the letters to uppercase (gb -> GB)

  2. For each character, get the ASCII integer code of the character

  3. Add 127397 to this integer

  4. Convert this integer to hexadecimal

  5. Prepend &#x and append ;

  6. Concatenate the result for both letters



Simples! The offset 127397 seems a bit arbitrary, but it does work.

In fact, I've written some code in PHP that does all of the above.


<?php

namespace ACA\Text\Emojis
{
use ACA\HTMLTags\IHTMLTextElement;
use ACA\HTMLTags\HTMLPrinter;

/**
* Convert a two-letter country code to an emoji flag
* @author Antony Charles Allen
* @since 8th August 2020
*/
class EmojiFlag implements IHTMLTextElement
{
private const OFFSET = 127397;

private string $content = '';

/**
* Construct an emoji flag
* @param string $country_code The two-letter country code (e.g. GB)
* @throws \InvalidArgumentException
*/
public function __construct(string $country_code)
{
if (!preg_match('/^[a-z]{2}$/i', $country_code)) throw new \InvalidArgumentException("Invalid country code [".$country_code.']');

$country_code = strtoupper($country_code);

for ($i=0; $i<2; $i++)
{
$letter = substr($country_code, $i, 1);

$ord = ord($letter);

if (!is_int($ord)) throw new \InvalidArgumentException("Unable to process character ".$letter.' in ['.$country_code.']');

$ord += self::OFFSET;

$hex = dechex($ord);

$this->content .= "&#x$hex;";
}
}


function TagName() : string
{
return 'span';
}

function Attributes() : array
{
return array('class' => 'emoji flag');
}

function Content() : string
{
return $this->content;
}

function __toString() : string
{
return HTMLPrinter::ToString($this);
}
}
}


Please feel free to use this code, modify it, have fun with it. It could also be done as a static function, but I've just chosen an instance constructor because I want to display the flag as a span-element in my HTML object model.
Hey you! I need your help!

Thanks for reading! All the content on this site is free, but I need your help to spread the word. Please support me by:

  1. Sharing my page on Facebook
  2. Tweeting my page on Twitter
  3. Posting my page on LinkedIn
  4. Bookmarking this site and returning in the near future
Thank you!