Posts categorized “PHP”.

Yii 1, PHP 7.1, yii-pdf and Mpdf

Mpdf 6.x only supports PHP versions up to 7.0. If you’re upgrading your local machine, or hosting environment to PHP 7.1 or beyond (you should be) then you’ll need to upgrade your Mpdf install to something more recent than 6. That requires a few changes.

Now just to make things complex here, the latest version of Mpdf happens to be version 7.1. From here on I’ll try and prefix any version numbers with either PHP or Mpdf.

Mpdf 7 and greater is composer install only. You could still download and copy the files into place, but I highly recommend using composer to manage your vendor packages in Yii (and Yii 2). It will save you hours and hours over time.

Mpdf 7 has updated it’s class name to be Mpdf with a capital M, and changed it’s construct method to accept a config array instead of separate parameters. Small but significant updates we’ll have to deal with.

If you’re already using composer, then you’ll have a composer.json file in the root of your codebase, and in there you should have a line which starts “mpdf/mpdf”.

That line will probably end something like “^6.0” orĀ “^6.4”

Assuming it’s less than “7.x.x” we’re going to update with composer.

Back up your codebase. I shouldn’t have to mention it, but do it, honest.

Run composer require mpdf/mpdf “^7.0”

That line will install the latest version, Mpdf 7.1, allow anything newer to be installed if you update in the future, and change your composer.json file (and likely your composer.lock file too) to include the newer information.

So we have the latest code, but we need to update Yii to use it.

yii-pdf wraps mpdf and makes it available via Yii->app()->ePdf->mpdf()

The yii-pdf config to get it functioning with Mpdf 7+ will look something like this:

'ePdf' => [
	'class' => 'application.extensions.yii-pdf.EYiiPdf',
	'params' => [
		'mpdf' => [
			'librarySourcePath' => 'vendor.mpdf.mpdf.src.*',
			'constants' => [
				'_MPDF_TEMP_PATH' => Yii::getPathOfAlias('application.runtime'),
			],
			'class'=>'\Mpdf\Mpdf',
			'defaultParams' => [
				'mode' => '',		//  This parameter specifies the mode of the new document.
				'format' => 'A4',	// format A4, A5, ...
			],
		],
	],
],

Note the librarySourcePath and class values. You can add your existing defaultParams and anything else which was in your preferences previously.

The last part is to update all places where you call the mpdf library. Previously it would have looks something like:

$mpdf = Yii::app()->ePdf->mpdf('UTF-8', '', 0, '', 15, 15, 15, 15, 8, 8);

We now convert the config to be an array of values:

$mpdf = Yii::app()->ePdf->mpdf(['UTF-8', '', 0, '', 15, 15, 15, 15, 8, 8]);

And that should be it. Update using composer, update your config, update all locations you instantiate mpdf. Then check your pdf generating code is still functioning.

Chrome browser masking PHP errors

I thought I was going mad for a while, but it turns out that sometimes spotting php error messages which come back from the server to the Google Chrome browser can be really tough.

If the error is inside an html element or attribute of an html element you’re going to struggle to see it in Google Chrome…

<a href="<?= $Model->fakeFunction(); ?>">link</a>

If $Model doesn’t have a method called fakeFunction then php will spit a “Fatal error: Call to a member function” error. The page that is displayed in Chrome won’t show you the error and viewing the source will also hide it from you.

Even the elements tab in Chrome Developer Tools won’t show it.

There only way I’ve been able to find the error content is to look at the network tab in Chrome and view the raw response of the document back from the server.

A few hours lost on this one!

Ping a url or script using IFTTT (with no repercussions)

Update: This actually doesn’t work as I’d hoped. Because flickr reports an error each time, eventually IFTTT disables the recipe after a few hours of calls. Back to the drawing board.

I’ve been trying to get IFTTT (if this then that) to send a call to a php script file when a trigger goes off for months. The problem wasn’t getting it to work in the first place, but for it not to leave any artifacts hanging around, or repercussions as I call them. I wanted the script to be triggered and that to be the end of it, with no files being created or errors being recorded.

An example of the problem would be the IFTTT Google Docs channel. You can upload a file to google docs from a url. You can define that url to be your php script and then tell your script to return a 404 (after it’s done its coding goodness) but when you view Google Docs a new file has still been created. If you want to use this for a large number of pings, you’re going to end up with a folder full of pointless files and a waste of your disc space. The Evernote and WordPress channels are a similar story. Even when you attempt to fail the call to your url (with a 404 or 503) they still create a note or post.

More… »

Yii (and Yii2) wildcard / catch all url rules

Sometimes you might want to do various checks of the url in yii config main and then send every other request to a particular controller.

The rule you need to add last to the urlManager is…

'(.*)' => 'controller/action',

'<url:(.*)>' => 'controller/action',

… and now any rule that isn’t matched previously will end up being sent to your defined controller and action.

In Yii2 you can also do the same:

'<url:(.*)>' => 'controller/action',

Considering local, dev and live environments

When you develop a website for a client you should usually be considering three or even four (if you also include staging) environments where one code base may be used. Local, development and live.

In this case you may want the code to behave slightly differently depending on where it’s being used.

A good example I regularly come across is when and where to send any emails that a system generates. When you are testing locally or on a development server you certainly don’t want to send out emails to people who have no knowledge of the system.

More… »