Skip to content

Fixing “Indirect Modification” Problems in PHP pre-5.4

I had a bizarre problem that had me banging my head against the wall for the last 24 hours that I was finally able to resolve. I’m putting up the solution I found in hopes that it helps some poor future Googler from repeating my same mistakes.

The situation was that I had a large PHP application developed with the fantastic Yii Framework that was working beautifully on my local machine as well as on my staging server. However, after deploying to the production server, I started getting the following PHP error all over the place:

Indirect modification of overloaded property some property has no effect…

Now for the uninitiated, the PHP engine prior to version 5.4 cannot do what is called “array dereferencing.” What is that? Suppose you have a method that returns an array, and that you want to use a particular element in that array right away. Example code:

function returnMyArray () {
	$myArray = array();
	$myArray['element'] = 'Find me!';
	return $myArray;
}
 
echo returnMyArray()['element']; // This will break.

In PHP 5.4 this will work, but not previous to. On my local dev machine I am running PHP 5.3.5, and the actual code situation was slightly different (magic getters and setters, see this post). After uploading to the production server, everything broke again. I refactored some code, but that still left some very weird errors in place, such as the following line that would not work:

$q->bindParam(':fid', $this->formId); // Where formId is an integer attribute of an object

That should really work, and it did on my local and staging servers. But not on my production, running PHP 5.3.10. AAAARRRGGGHHHH!!!!!

Temporary Solution

I will give you how I solved it, but then add a disclaimer about the solution. In my case, a simple, one line change to the error reporting levels was the solution. On my local and staging servers in php.ini was set to:

error_reporting  =  E_ALL & ~E_NOTICE & ~E_DEPRECATED

And on the production server? Missing that critical ~E_NOTICE. Adding ~E_NOTICE back in to my php.ini on the production server prevented the errors from being output. Due to a unique configuration of the production box which was out of my control, the NOTICE that was being generated by those types of lines was enough to stop the whole process. The application still works with those errors ignored, and I am back in happy land.

But what does that line do? The configuration signals to PHP to turn on and report ALL errors, except for NOTICEs and DEPRECATED warnings. By default, PHP ships with ALL errors on but NOTICE errors off. NOTICE errors are very handy to have on during development and debugging, because they can catch silly mistakes like uninitialized variables or ambiguous array indexes (slightly different than the problem I was facing). See this great StackOverflow post for some examples and suggestions. Now, in my case, I had verified that the code as written was actually conformant and functioning properly (in fact, the specific error was extremely related to this specific issue mentioned on SO). In this one case it was determined by the team to be safe to not have that particular error reported, because it was effecting the flow of the application.

However, do realize that turning off NOTICE errors may reduce your visibility into problems in your code. On a production box, it may be good to have the errors off as PHP ships by default, so that your users do not see them even if they should exist. But running all the time with NOTICE off during development may cause you to miss issues. Be aware when you modify the error reporting levels, and understand what you are doing.

Now I am just waiting for PHP 5.4 to get into the CentOS yum repository…

Published inProgramming

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *