Weird PHP method behavior does not exist but is in code - php

Does anyone have a clue about this? PHP 5.2.13. Results not wholly consistent i.e. could get a good result with a page at one time, then get an error at another.
The error is fatal - class does not have method.
But the following are true:
The class is defined in only one place and has the relevant method in the code.
At the point where failure occurs: reflection shows that the method exists.
At the point where failure occurs: method_exists says the method does not exist.
Previous calls (they're all static - not my choice) earlier in the code worked.

May be it's related: http://bugs.php.net/bug.php?id=51425
But I think here we have some cache-related problem. Do you have some cache enabled? Like APC or any other accelerators?

Be sure that the file containing the method is included. If the method is in a class, make sure the class instance is created and the method is called through the class.
Maybe you are missing the class instance?

Related

How to show namespace-use errors?

Is there any way to get any sort of error, be it exceptions, error codes or logging, for when the aliasee introduced by use does not exist?
For example, I tried this one (i.e. using all error signalling I know of):
<?php
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(E_ALL);
use \Foobar as Frob; // \Foobar is actually unknown
print("still here\n");
Together with this line of command in Bash:
display_errors=on php love.php
and get:
still here
as the sole output. I looked into php_errors.log, but nothing is there.
PHP designers, in their much valued sanity, surely have thought of something?
I understand use is just an alias for alias in the world of PHP, yet I don't see why there should not be errors for fully qualified referees.
use statements as such don't really do anything much. All they do is alias a namespaced name to another name of your choice, henceforth allowing you to refer to that shortened alias instead of the full name. That's it. Nothing more happens. The class/function/file isn't actually being loaded at this point nor any other sort of validation is being done. This is because there are many ways to load the actual class that alias refers to, and you may want to do this after the fact later on. Most likely using an autoloader, which will attempt to load the class when it's first actually used.
So: no, there's no way besides trying to use the class.
$frob = new Frob; // Fatal error: class Foobar not found
PHP does not report any error because there is no error in your code.
The use declaration says that Frob is just another name for \Foobar. It is just a declaration, PHP does not try to load \Foobar or check if it exists at that point.
As long as you don't use either Frob or \Foobar in the code, that use declaration has no effect.
But if you try to use it:
$frob = new Frob();
and \Foobar is not a class then be sure PHP will trigger a fatal error and stop the execution of the script.
The use declaration works like the symbolic links in the file system. You can create the file a that is a symbolic link to b and as long as you don't try to read from a (or b), nobody cares if b exists or not.

Class 'XMLParser' not found

I've created a class called XMLParser which is being inlcuded using an auto include like all the other classes I'm working with.
When I try to instantiate an object using this class, I get the fatal error in the title.
The auto-include function works. Changing the class name makes it work, I'm also quite positive this had been working when I set it up, otherwise the unit tests depending on this class would never have passed.
Is there a built in XMLParser class that could be conflicting with this?
Surely, even if there was that would not be a problem as I'd get a declaration error or the object would just be instantiated anyway?
Any light on the matter would really help. It's frustrating to say the least.
There is a PEAR file called XMLParser.php
This file appears in the PHP include path before my class directories.
When the autoload function requires_once XMLParser.php it finds this file, which rightfully, does not have the XMLParser class defined within.
That's the source of the fatal error.
To avoid this, one should probably namespace their classes.
Shame on me, thanks for all your feedback.

Call to undefined method in class even when it is defined

I am getting the following error message turning up in my apache error logs:
PHP Fatal error: Call to undefined method MyWebsite\Model\ContentMedia::getImagePath() in /var/www/www.website.com/application/libraries/MyWebsite/Model/ContentVersion.php on line 544
On line 544 of ContentVersion.php the call is made:
$cm->getImagePath('img', 'small');
The ContentMedia class extends another class called Model that does have that method:
class ContentMedia extends \MyWebsite\Model{
... the Model class:
namespace MyWebsite;
class Model{
public function getImagePath($field, $size = null){
...
}
I get this error show up every now and then in the log files, so it may be one particular instance where a user comes across this, but I don't know where. This method is used throughout the site and it works. If the method is definitely defined how can this error be thrown?
I thought about checking the access logs to match an exact requested URL to the timestamp of the error, but the access logs are insanely large of course, so any advice as to how to output just a chunk of time from a large access log would be amazing.
I am using Doctrine 2 and Codeigniter 2.
My first thought is to check that you definitely have an instance of model present within the script. Have you tried creating another function for the sake of testing that will just echo something like "Object is instantiated and inherited functions properly".
That way we might be able to narrow down the problem a little

Catching "Call to a member function foo() on a non-object" errors

Is there a way to catch Call to a member function foo() on a non-object in PHP? It does not sound that serious (as far as fatal errors go), but the shutdown function does not seem to be called at all (PHP 5.3, Debian).
Update:
How to prevent such errors is really not the point. Sure, one should check for null whenever that is an expected possibility, but littering every single object member function reference with error checking code would result in bloated and unreadable code. Hunting down the occassional error based on the logs is fine - the problem is that logs are not very useful for fatal errors. Using a shutdown function would solve that nicely, but I can't get it to work with this specific type of error; which seems strange to me, because it is not an error which would leave the PHP interpreter in a particularly messy state.
I hope this does not sound silly - but you should make sure you know what you are working with. Use instanceof or is_object where you need - or fix the source of the problem - why is that variable not an object in the first place?
I suggest to just ensure, that it is an object. Using methods/functions you can use type hints
public function x (myClass $object) {
$object->foo();
}
else you may use is_object(). At the end such a message sounds like there is a bug within you application, that should be fixed before release, or -- if such a situation can occur by design -- verify the type (is_object() (see above) or !is_null($obj) or something like that) before trying to call something, that does not exist.

On error, attempt to include a file and re-execute the failed function

First of all, this question is purely theoretical. Fact is, whether it's possible or not, it would be terribly bad practice. Having said that, here's my question:
PHP offers the possibility to define custom error handlers via the set_error_handler function. By parsing the error message, it's possible to find out what triggered the error.
I'm interested mostly in 'Call to undefined function' errors. I know its possible to parse the error message to uncover the called function, and this got me thinking.
Would it be possible for the error handler, in case of an Undefined Function, to attempt to include a file (say functions.html.php for all functions starting with a html_ prefix), and then attempt to re-execute the function, plus arguments, that initially triggered the error? And, most importantly, return the function's value in case of success?
In brief without using exception handling you won't be able to recover from the error in the way you described.
There is a way to handle this specifically for undefined functions, however that is to say undefined member functions from an object. This is the __call() method. Basically if you call an undefined method from an object __call() then takes that function call and does whatever you put in the method body see http://php.net/manual/en/language.oop5.overloading.phplink text
It's not really possible to restart the execution where the error occured.
However: there is a system to loading classes on demand, using the __autoload function.
From the manual:-
You may define an __autoload function which is automatically called in case you are trying to use a class/interface which hasn't been defined yet. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error.
There is more in the PHP manual here: http://php.net/manual/en/language.oop5.autoload.php

Categories