Category Archives: CodeUnit

CodeUnit houses software and programming tips, snippets and tutorials, complemented with the occasional hardware review.

PHP: “JPEG library reports unrecoverable error: Not a JPEG file: starts with 0x89 0x50” Error Solved Tips, Tricks and Tutorials 30 OCT 2017

My cross-platform Kinetica TouchandTell app running on an old iPad 3 was not successfully uploading images to our new RedStation hosted Ubuntu server (the Android builds were doing it just fine), and I wasn’t really sure why. The Appcelerator Titanium code seemed all okay and in fact it wasn’t until I checked the server’s PHP error logs that I finally spotted the reason why. Exhibit A:

“JPEG library reports unrecoverable error: Not a JPEG file: starts with 0x89 0x50”

Some quick Googling led me to understand that the PHP GD library was failing when trying to parse the received JPG file from the iPad, primarily because the supplied photo was not in the accepted JPEG format. (In fact, chances are that the encoding is in fact either that of a PNG file or perhaps the brand new HEIC image format that has just rolled out with iOS 11).

Although the documentation states that the old imagecreatefromjpeg function is meant to return FALSE if it fails to open the supplied file, there is (annoyingly) a listed bug tracking the fact that the function is in practice actually triggering a Fatal Error instead!

So instead of adopting a practice of trying to open an image based on its file extension, a better solution to get around this problem would be to make use of the similar imagecreatefromstring function, which returns an image resource representing the photo obtained from the given file.

In practice:

$image = false;
$image_data = file_get_contents($imagefilepath);
try {
      $image = imagecreatefromstring($image_data);
} catch (Exception $ex) {
      $image = false;
}
if ($image !== false){
//process $image resource
}

(These image types will be automatically detected if your build of PHP supports them: JPEG, PNG, GIF, BMP, WBMP, and GD2.)

Related Link: imagecreatefromstring

MacBook Air and Xcode: Free up Disk Space by Removing Unwanted/Unavailable Device Simulators Tips, Tricks and Tutorials 29 OCT 2017

iOS software development on a MacBook Air inevitably then means that you have a couple of Xcode versions installed on your device, and as we all know, these chew up a fair bit of disk space in the process. One way to free up some disk space is to remove some of the unwanted or perhaps unavailable device simulators that build up with each Xcode update.

The first step is of course to see what you do in fact have installed, and the easiest is to do this is to make use of the simctl tool that comes with Xcode 6+. To do this, launch a terminal and run:

xcrun simctl list devices

Note the use of xcrun to locate and execute the latest development tools. In a user friendly twist, simctl allows you to bulk delete all unavailable simulators with:

xcrun simctl delete unavailable

You can also target specific devices for deletion by simply specifying them either by name or ID:

xcrun simctl delete D26C18BC-268C-6F0B-9CD8-8EFFDE6619E3

This process can actually free up quite a bit of space, particularly if you’ve been through a number of Xcode updates in the past.

Related Link: Xcode

MySQL: Solve sql_mode=only_full_group_by Error by Turning off Strict SQL Mode Tips, Tricks and Tutorials 26 OCT 2017

When moving an older MySQL-based project to a new server instance, one of the SQL query errors bound to immediately strike is that of triggering the sql_mode=only_full_group error, caused by your SQL select statements referring to columns that are not functionally dependent on the GROUP BY column. (Best explained here in the MySQL documentation)

This new, “Strict SQL Mode” (which is actually a collection of enabled “Server SQL Modes”) is now switched on by default for any MySQL Server 5.7 and up installation, and because in the real world refactoring an entire project just to suit these new settings isn’t really an option, to resolve the issue you need to “disable” this new default on your server instance.

The two newly enabled SQL mode setting that we want to target (because they are the main culprits here) are STRICT_TRANS_TABLES and ONLY_FULL_GROUP_BY.

To do this, you first need to create an additional configuration file for your MySQL server instance:

sudo nano /etc/mysql/conf.d/disable_strict_mode.cnf

Add these two lines to the blank file and then save your changes.

[mysqld]
sql_mode=IGNORE_SPACE,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

As you can see, essentially what we are doing is just declaring a new SQL mode with our two culprit modes omitted.

Finally, restart the MySQL server with:

sudo service mysql restart

Try running your fault trigger SQL statement again, and you should now no longer get this error message staring back at you any more:

Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'yourdbname.tblname.address' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

Related Link: MySQL Group By Handling | Server SQL Modes

Ubuntu Server: How To Enable OPcache for PHP 7 on Apache Tips, Tricks and Tutorials 23 OCT 2017

PHP is what is known as an interpreted coding language, meaning that unlike compiled apps that have already been compiled down into bytecode (i.e. you have to compile your application first so that the OS can run it), PHP scripts are only compiled and interpreted by the runtime engine on script request.

So, if you have scripts that are relatively static (i.e. you aren’t changing them very often), one good way to accelerate your PHP project is to use some sort of caching system that essentially pre-compiles your scripts down to bytecode, meaning less work come request time and thus theoretically, faster code execution.

Enter opcode caching. OPcache, originally a closed source part of the Zend Server project (under the moniker of Zend Optimizer), is an open source module that stores (caches) precompiled PHP script bytecode in shared memory, thus removing the need for PHP to first load and parse scripts on each request.

Since PHP 5.5.0, the module has come bundled with PHP (though disabled by default), meaning that for all intents and purposes, OPcache is now pretty much the standard when it comes to PHP accelerating.

To set up OPcache on an Ubuntu 16.04 server running PHP 7 over Apache, you first need to enable OPcache via the standard php.ini file. To edit the file:

sudo nano /etc/php/7.0/apache2/php.ini

To enable the module once you have the php.ini file is open, find the line reading ;opcache.enable=0, uncomment it by removing the ; and then enable by changing the 0 to 1:

opcache.enable=1

There are quite a few OPcache related settings that you can change while doing the setup, with the php.ini doing a good job of explaining the role of each one. The important ones to keep track of are: opcache.memory_consumption, opcache.max_accelerated_files, and opcache_revalidate_freq.

Save your changes and then enable the module via:

sudo phpenmod opcache

Finally, restart PHP:

sudo service apache2 restart

Monitoring OPCache is a whole other story (worth a google), but the easiest way just to make sure that it is in fact running is to call phpinfo() on one of your webpages. If enabled, you’ll see a bold section under the title of Zend OPcache, with the first column “Opcode Caching” listing a value of “Up and Running”.

Related Link: PHP OPcache | Wikipedia

Changing the Hostname in Ubuntu Server 16.04: Unit hostname.service is masked Tips, Tricks and Tutorials 03 OCT 2017

For older versions of Ubuntu, many of the tutorials online show you how to edit your server’s hostname by simply editing /etc/hostname and then restarting the service with “service hostname restart”.

However, attempting this on a 16.04 Ubuntu Server build will most likely fail with the following error message:

Failed to restart hostname.service: Unit hostname.service is masked.

As it turns out, the new way of changing your hostname on systems running systemd (i.e. Ubuntu 16.04) requires you to use the hostnamectl command, meaning that to set your new hostname you need to run:

sudo hostnamectl set-hostname NEWNAME

(Where obviously NEWNAME is the new/desired hostname that you want to use).

You can check that the change has been affected by running:

hostname

Worth jotting down here for future reference.

FPDF: How to use a Degree Symbol in a Generated PDF Tips, Tricks and Tutorials 29 SEP 2017

I’ve been using the FPDF PDF generator library for years now as the de facto method for my PHP projects to produce PDF reports. However, one minor annoyance is that the generated PDF files often falter when it comes to the inclusion of certain special characters – like the degree symbol (°) as an example.  (Basically, something like °C becomes °C in the final document)

The reason for this happening is that Arial, the default used/included font, is of type ISO-8859-1 while the degree symbol is UTF-8 encoded. So in order for us to include special symbols or characters from other languages, we need to either try and convert them into our font compatible ISO-8859-1 format, or perhaps switch to using a different TrueType or Type1 font (which then would contain the desired character set).

Now while UTF-8 support is available via a modified class, the easiest way to fix the degree symbol issue without having doing any real work is to simply make use of the PHP utf8_decode function, which convert UTF-8 encoded strings to their ISO-8859-1 equivalents.

In other words outputting utf8_decode(“°C”) to your PDF should result in the expected °C

Related Link: FPDF PDF Generator Library

Ubuntu Server: How to change or set the Timezone Tips, Tricks and Tutorials 29 SEP 2017

Dropping this as a quick reminder to myself. When confronted with a new Ubuntu server instance, I can check the currently set time zone by simply asking for the current time with

date

Now if I need to change the currently set time zone to something else, the easiest would be to just run

sudo dpkg-reconfigure tzdata

This should bring up an easy to use graphical interface that will allow you to select the correct geographical region/city time zone that you wish to have your server reflect.

Note: Because your cron jobs all depends on this information, it is a VERY good idea to restart the cron service after making your timezone change:

sudo service cron restart

Also worth pointing out, if you are not particularly sure on which city time zone to choose, you could always select the geographic area “Etc” and then choose from the more generic options like GMT or GMT+2.

(UPDATE: Oh. Turns out that that I’ve left this note for myself before. I may need to rethink my note system.)

Related Link: Ubuntu Server

MacBook Air: How to Update Node.js Tips, Tricks and Tutorials 14 MAR 2017

Ugh. I needed to fire up the loan MacBook Air to do an iOS compile of my recently completed Appcelerator app. Naturally, I started off on the wrong foot by not recalling the MacBook’s password (luckily I found that I had mailed it to myself some time ago, so I did eventually get in). Then Appcelerator moaned that it needed an update, which failed because it needed a newer version of Node.js to be installed.

So off to Google I once more marched, the result of which I am now jotting down here as a future reminder: How to Update Node.js on a MacBook Air.

As it turns out, updating node.js is a pretty quick affair: First, fire up a terminal (which again I needed to march over to Google in order to learn how to do), and then run the following commands:

sudo npm cache clean -f
sudo npm install -g n
sudo n stable

Note the use of sudo to run these commands. Essentially we are first force clearing the npm cache, then installing and upgrading node to the latest version.

Related Link: MacBook Air | Node.js