It’s been a while since I published my Getting Started with PHP on GAE Article, and the platform has been doing better than anyone had expected. The PHP feature request is still at the top of the NFR list, and the Phalcon NFR I created way back then is now sitting at top 17, indicating not only Phalcon’s spread and popularity, but also the liveliness of the PHP community and our desire to see it spread into professional large scale enterprise environments.
On February 26th, the PHP and Python end of GoogleAppEngine’s SDK were updated to version 1.9.0, and this article will aim to explain what was changed regarding PHP. You can find the full release notes here.
New Interpreter Minor Version
The PHP interpreter has been upgraded from PHP 5.4.19 to PHP 5.4.22.
I’m not sure why GAE isn’t using the latest version of PHP, but any upgrade is a good upgrade.
5.4.20 fixed several dozen bugs present in 5.4.19, relating to segfaults, incorrect space character encoding when using quoted-printable mode, memory leaks (particularly in cURL), some extension related fixes, and more.
5.4.21. prevented the triggering of auto loading on compile time errors, made sure the built in server treated all http headers as case-insensitive, improved error messages in the DateTime class, fixed IMAP’s configure script and more.
Finally, 5.4.22. fixed some more bugs relating to the built-in server, FTP, Exif, ODBC, Sockets, XMLReader, and other components. You can see the full differences in the version 5 changelog.
The latest version of 5.4. is 5.4.26., and we hope GAE adopts it soon, as it does contain some important fixes.
Autoloading SDK files
Autoloading is now available in the SDK so developers will no longer need to explicitly require SDK files.
Previously, to use SDK classes for Google specific services on GAE, you had to manually include them or write an autoloader that did it for you. These classes are now autoloaded by default, so using a class like
google\appengine\api\mail\Message is as simple as referencing it.
All examples on the GAE SDK documentation site have been updated to reflect this.
you now have only
Includes from buckets
Expanded php.ini setting
google_appengine.allow_include_gs_buckets to allow a path filter to be included for improved security.
E_USER_WARNING warning message is now triggered if an application moves a user uploaded file to a Google Cloud Storage bucket/path. This is due to the fact that code may be included and lead to a local file inclusion vulnerability.
These two upgrades come in tandem.
It is generally possible to include files from Google Cloud Storage buckets, as long as those buckets are defined in the
php.ini file under the option
google_appengine.allow_include_gs_buckets. The value of this setting is a string with comma separated values, like so:
The first update means we can now include subfolders in the bucket paths for added security. So instead of allowing includes from anywhere in bucket_1, we can allow includes only from
bucket_1/includes_allowed, like so:
google_app_engine.allow_include_gs_buckets = "bucket_1/includes_allowed"
This lets you use your bucket for several aspects – classes and files to include, and general storage of other types.
The second update means that PHP will emit a warning if you perform the move of an uploaded file into an include-allowed bucket. This is to make sure your users can’t upload PHP scripts into a folder from which they can be included, to prevent LFI attacks. When you see this warning, you should modify your app so that it moves user uploads to an include-disallowed part of the bucket.
Newly created App Engine applications now have a Google Cloud Storage bucket created automatically as part of the same Google Cloud Project.
Previously, if you wanted a Google Cloud Storage bucket for file writes, you had to create one separately and configure it for use with your GAE PHP app. However, since PHP apps so often require disk reads and writes and moving user-uploaded files, the 1.9.0 release automatically creates a fully configured bucket as you start a new project.
This bucket has a free quota of 5GB total storage, so your app does not need to be made billable, and can be accessed via the name
<app_id>.appspot.com through the
gs:// protocol, where
app_id is your app’s ID. You can find the name out in the Admin Console under Application Settings, as well.
Find out more about setting it up and using it here.
Fixed an issue with empty Google Cloud Storage folders not displaying correctly in the Developers Console. New folders are now created using the “/” suffix instead of “$folder” so that they are displayed correctly.
Added API functions
CloudStorageTools::getContentType() for retrieving the metadata and content type of Google Cloud Storage objects.
The GCS objects you store can also tell you some of their metadata through the new
CloudStorageTools::getContentType() API. To see the full API reference of
CloudStorageTools, see here.
PHP_SELF and SCRIPT_NAME fix
Due to two bugs, 9989 and 10478, PHP_SELF and SCRIPT_NAME gave the wrong output. This has now been fixed.
If you’re wondering where you might want to use these – they’re most commonly used by routing, autoloaders, factory patten realizations, and similar projects where the script being executed has to be aware of its environment.
Previous Versions of the SDK
Previous versions of the SDK added support for the FTP and Zip extension, fixed some more GCS bugs, allowed the sockets API for Billing Enabled Apps, added a
CloudStorageTools::getPublicUrl() API for generating a URL for public access to Google Cloud Storage objects, and more. To see the full list, check out the changelog.
GoogleAppEngine’s PHP support has been steadily growing since it was announced, and it’s just heating up. With HHVM on one front, Zephir on the other, and Google-powered PHP in the cloud on the third front, a highly productive war seems to be brewing on the horizon, and whoever wins, the PHP community will benefit. Who do you vote for? Do you use GAE for your PHP apps? Have any interesting deployments you’d like to show us? Would you like to see some more advanced implementation examples? Let us know!