Press "Enter" to skip to content

Tag: php

Code Snippets: UTF-8 to UTF-16 revisited and expanded

Yes, I know I posted yesterday about converting from UTF-8 to UTF-16BE/UTF-16LE – but I wasn’t happy with the code to convert to UTF16. It relied on mb_convert_encoding which whilst clear, it did mean that sequences sent could be silently “fixed”, lone high/low surrogate code points would be refused to be output (which I actually needed as they were one thing I was trying to test against!), and I just wanted more “insight” into the whole UTF8 to UTF16 system.

Unicode is NOT UTF-8

One thing to remember (and which caused me a timesink) was that Unicode is NOT UTF-8! Unicode is a collection of characters which are usually represented in UTF-8 byte sequences (but can be represented in UTF-16BE/UTF-16LE and UTF32 and others).

Code Snippets: PHP: Converting to/from UTF-8 to UTF16-BE

I needed to convert some Unicode UTF16-BE strings (as used in Java) to UTF-8 (which is “byte-orientated” and so doesn’t need to worry about endianness) – however, there didn’t seem to many examples online. I’m not going to say these methods are robust, 100% accurate for every use case or even the best way to do it – but just ways to do it.

It’s worth noting that Java uses the escape sequence \uXXXX (where X is a hexadecimal code), and PHP uses the nearly similar escape sequence \u{XXXX} . Both seem to use \xXX for a single character.

ADDED: I’ve improved the UTF-8 to UTF-16 code conversion in a newer post.

PHP SplFileInfo string values

Whilst PHP’s documentation of SplFileInfo isn’t “bad” as such, it can be tricky to remember what string functions (such as getBasename, getExtension, getFilename, getPath, getPathname, getRealPath and __toString) return under which circumstances. Hence this post!

To generate this data, we’re going to start off with a RecursiveDirectoryIterator with an optional callback filter (to enable us to later on, filter the returned values):

<?php 
$directoryIterator=new \RecursiveDirectoryIterator(
            '/var/task', // test directory
            \RecursiveDirectoryIterator::SKIP_DOTS // ignore "dot files"
        );
       
        $filterIterator = new \CallbackFilterIterator(
            new \RecursiveIteratorIterator($directoryIterator), 
            function (\SplFileInfo $file) {
           // add filter conditions here
            return true;
        });
        /** @var \SplFileInfo $fileInfo */
        foreach ($filterIterator as $fileInfo) {
            $objectNames= [
                'fileInfo',
                'directoryIterator',
                'filterIterator'
            ]; // which objects (defined above) are we interested in
          $methods = [
                'getBasename',
                'getExtension',
                'getFilename',
                'getPath',
                'getPathname',
                'getRealPath',
                '__toString'
            ]; // which methods of those objects do we want to get. 
           foreach ($objectNames as $objectName) {
               foreach ($methods as $method) {
                    print $objectName . '->' .
                        $method . ' = ' .
                        call_user_func([$$objectName, $method]) .
                        PHP_EOL;
               }
           }
           die(); // we only want the first one as an example
        }

Give the file /var/task/assets/fonts/montserrat-v14-latin-700.eot and the “start” directory of /var/task , we get the following:

  • fileInfo->getBasename = montserrat-v14-latin-700.eot
  • fileInfo->getExtension = eot
  • fileInfo->getFilename = montserrat-v14-latin-700.eot
  • fileInfo->getPath = /var/task/assets/fonts
  • fileInfo->getPathname = /var/task/assets/fonts/montserrat-v14-latin-700.eot
  • fileInfo->getRealPath = /var/task/assets/fonts/montserrat-v14-latin-700.eot
  • fileInfo->__toString = /var/task/assets/fonts/montserrat-v14-latin-700.eot
  • directoryIterator->getBasename = assets
  • directoryIterator->getExtension =
  • directoryIterator->getFilename = assets
  • directoryIterator->getPath = /var/task
  • directoryIterator->getPathname = /var/task/assets
  • directoryIterator->getRealPath = /var/task/assets
  • directoryIterator->__toString = assets
  • filterIterator->getBasename = montserrat-v14-latin-700.eot
  • filterIterator->getExtension = eot
  • filterIterator->getFilename = montserrat-v14-latin-700.eot
  • filterIterator->getPath = /var/task/assets/fonts
  • filterIterator->getPathname = /var/task/assets/fonts/montserrat-v14-latin-700.eot
  • filterIterator->getRealPath = /var/task/assets/fonts/montserrat-v14-latin-700.eot
  • filterIterator->__toString = montserrat-v14-latin-700.eot

Hope it’s useful to someone!

[Techy] Getting cURL to work with Let’s Encrypt: unable to get local issuer certificate error

On my test Debian jessie 8.2 and a staging server Ubuntu trusty 14.04, I had problems being able to use cURL to fetch data from a remote HTTPs site which was secured using a free Let’s Encrypt certificate (this problem manifested itself via both PHP 7 cURL functions and curl directly).

An example of the error is:

curl --verbose https://helloworld.letsencrypt.org/
...
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

To fix this, I found the following steps worked:
sudo apt-get install --reinstall ca-certificates
to ensure you have the latest certificates by your distribution – this might help you, but it didn’t assist me 🙁

So I downloaded the Let’s Encrypt root certificates and forced a rebuild of the certificate store:

sudo curl https://letsencrypt.org/certs/isrgrootx1.pem.txt -o /usr/local/share/ca-certificates/isrgrootx1.crt
sudo curl https://letsencrypt.org/certs/letsencryptauthorityx1.pem.txt -o /usr/local/share/ca-certificates/letsencryptauthorityx1.crt
sudo curl https://letsencrypt.org/certs/letsencryptauthorityx2.pem.txt -o /usr/local/share/ca-certificates/letsencryptauthorityx2.crt
sudo curl https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem.txt -o /usr/local/share/ca-certificates/letsencryptx1.crt
sudo curl https://letsencrypt.org/certs/lets-encrypt-x2-cross-signed.pem.txt -o /usr/local/share/ca-certificates/letsencryptx2.crt
sudo curl https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt -o /usr/local/share/ca-certificates/letsencryptx3.crt
sudo curl https://letsencrypt.org/certs/lets-encrypt-x4-cross-signed.pem.txt -o /usr/local/share/ca-certificates/letsencryptx4.crt
sudo dpkg-reconfigure ca-certificates

and everything worked!

If you are running Java, you may need to also add the certificates to the Java Keytool:
keytool -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -file /usr/local/share/ca-certificates/isrgrootx1.crt
keytool -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -file /usr/local/share/ca-certificates/letsencryptauthorityx1.crt

(change the storepass password [default of “changeme”] to whatever is relevant to you)

Jobs ahoy!

I know of quite a few companies currently recruiting – so if you are job hunting and think any of the following are of interest to you, please get in contact:

Leicester based
Senior Magento Developer
Senior Digital Designer
WordPress Developer
Account Manager

London based
Account Manager
Big Data Engineer
DevOps Engineer / Big Data SysAdmin
Machine Learning Specialist
Partnership Development Manager?

Guidford based
Sales Executive
DevOps Engineer
Python Software Developer
Systems Administrator

Brighton based
Java Developer
Head of User Experience and Design (UI / UX)
Senior Designer/UI Developer
Accountant
Senior Accountant
Trainee Account Manager (Finance Industry)
Outbound Sales Advisor

UK (contract/remote work)
WordPress Developer (up to £30/per hour)
Senior WordPress Developer (up to £45/per hour)
Symfony Developer