call_user_func_array vs. call_user_func - php

I ran across an interesting issue today. We have an application that utilizes Zend Frameworks caching functionality. A request to this application typically calls a factory method using the following line
$result = call_user_func_array(array("myclass", "factory"), array($id));
The idea is to return an object from the factory method that we can access later on. When we implemented a caching feature, this call just, well, dies. No errors, just a white screen. Nothing in the error log. We can error log the line before ok, but trying to error_log inside the factory method does nothing.
Interestingly enough, changing the line to :
$result = call_user_func(array("myclass", "factory"), $id);
fixes the issue.
We've spent a few hours looking around for bug reports and haven't come up with much to explain this behavior. Thoughts anyone?

I have had issues like this that came down to __autoload not firing properly when a not-yet-loaded class was invoked through a PHP command. No other strategy than dumb trial and error for it as far as I know, just try if a line explicitly invoking the class before the PHP command solves it for you.
$dummy = new MyClassName;
call_user_func_array(array('MyClassName', 'method'), array($id));
unset($dummy);

Which version of php are you using? There was an issue in combining call_user_func_array with ReflectionClass at one point. I'm not sure if it's fixed yet.

Is it segfaulting? Check your 'root' apache logs (outside of any virtualhost) and see whats going on. If that thread is segfaulting you may want to persue that on the PHP mailing lists and/or bug tracker.
Alternately you could try running http in single user mode, in GDB, with a debug-compile of php and see if you can capture it, but thats a lot of work :-)

Related

Compile-time PHP errors in VSCode

Has anyone configured VS Code to show syntax/semantic errors in PHP development? Coming from full Visual Studio/C# world, I really miss this thing a lot. Currently I actually have to call my PHP function using a client, only to get a HTTP 500 error and then check server logs to see what went wrong. This is a huge pain. Going through all of this only to find for example that I didn't import a require namespace, is so frustrating.
I understand that PHP by design cannot detect all kinds of errors like C# at compile time (so to speak), but detecting functions that do not exist or not passing required parameters should be easy to catch.
Is there a plug-in or setting in VS Code that could handle syntax/semantic error in PHP code? I'm using Laravel on the server-side, if that matters.
Looks like I found something. I uninstalled PHP Intellisense extension this morning and installed PHP Intelephense and all seems to be far better. Not only that the syntax and semantic errors are highlighted, it automatically injects required namespaces too. And if that were not enough, Go To Definition (F12) command has started working correctly all of a suden. :)
Must-have extension for any PHP work in VSCode I'd say.

Debugging PHP Code with debug_backtrace

I love to save time using someone else's code. And I want to start effectively debugging my scripts, as well as scripts I inherit from other developers.
I've been reading up on debug_backtrace(), and I'm not sure if it's what I'm looking for.
Basically,when a class is instantiated I want to know what methods are being fired.
Truthfully, I'd like to know as much as possible, but knowing what's going on inside a single class would be fantastic.
<?php
require('aHugeComplicatedClass.php'); // sooooo many methods
try {
$obj = new aHugeComplicatedClass($params);
}
catch(Exception $ex){
var_dump($ex);
}
?>
From PHP's docs about debug_backtrace, it looks like I need to place the debug_backtrace() function inside each method/function within any and all classes, just to see how it was reached.
I gotta be reading this too literal. That would be a ton of modifications.
So, if I have a php file, that instantiates a class, and I know this class is extended from other classes, what's the simpliest way to debug that Object?
I would install XDebug and hook up the remote debugging to your IDE (e.g PhpStorm or Eclipse), that way you will get nice stack dumps on all errors, plus the ability to breakpoint your code and inspect the stack and all object internals at your leisure.
http://xdebug.org/
You can also use it to profile your application call chains without making any code changes (which sounds more like what you are wanting). By using the profiling options, which generate big log files, you can then load these logs into webgrind and visually inspect who's calling what in nice tree structures.
https://code.google.com/p/webgrind/
The Zend tool chain would also provide this kind of deeper debugging functionality out of the box.
Alternatively install an Application Performance Monitoring agent such as App Dynamics or New Relic for similar code-profiling. This is most useful for remote installations (i.e. production) where debugging isn't an option and profiling is expensive.
We use NuSphere PhpED for getting all such things. It can trigger debugger to stop on specified exceptions and/or errors and shows complete call-stack that may include php functions calls, php method calls, embedded functions calls and embedded method calls.
http://www.nusphere.com/products/phped.htm
I was told in the beginning that their debugger is the best and can confirm this. It stems from the OSS project
http://sourceforge.net/projects/dbg2/
With PhpED IDE we run full cycle of development -- coding, debugging, profiling, testing and uploading to the production server.

Can't configure ZEND to work

I tried both ZF 1.12.0 and 2.0.3, then ran this code:
On my computer it didn't work and seemed to stuck in this line:
$videoEntry = $yt->newVideoEntry();
I know that because when I put two echos around that line, only the first got displayed.
The weird thing is that there is no such method called newVideoEntry() anywhere, at all.
And the most annoying thing is that it works completely fine on phpcloud, which turn out to be using ZF 1.11.11, an old version that I can't find anywhere on the internet.
I'm really lost. Any idea? Which version I should use, since they are so much different and incompatible. Any solution for that code ?
Method newVideoEntry() does not exist because it is a magical method. Zend_Gdata_App::__call takes care of that. It creates Zend_Gdata_YouTube_VideoEntry and things go on.
if you want to use the same library as phpcloud all you have to do is to pull the content of the zf library that is hosted on the php cloud server. dont remember where it is exactly but should be in a zend folder on the phpcloud server.
As for the error you get , without the exact error message it is hard to tell what's wrong.

PHP - Is there a way to ignore fatal errors in php.ini/ini_settings only without modifying the code?

I inherited some PHP source code, and I have to maintain it. It has been built from scratch using no framework, just the former developer's own creation.
Now, I ask this:
Is there a way to ignore fatal errors in php.ini/ini_settings only without modifying the code?
Scenario:
SomeClass.php:
<?php class SomeClass {
...)?>
index.php:
include("SomeClass.php");
...
include("SomeClass.php");
In my development box, this throws a Fatal Error exception (because SomeClass has been declared twice), which is the obvious and expected behavior.
Here is the kicker: This source is hosted somewhere, and it works. I just don't ANY access to that server.
So I see here two scenarios:
1.) There is a way to silence this Fatal Error via 2 includes by an ini setting. This I have to know.
2.) The former developer did NOT give me the exact, updated source code that is currently up and running. I then have to insist that he give me the latest source code, but I can only do this if I am 100% sure that there is no way #1 can happen.
What do you guys think?
I tried setting a set_error_handler() function that doesn't die on fatal errors, but instead Apache crashed. In other words, PHP needs to die so that the system doesn't.
So, sorry, I really don't think there is a solution for that.
Fatal errors don't come from the include function - only warnings. You'd get fatals from require, though. Use #include and it won't even generate the warning.
Error reporting is mostly discouraged on production servers. Why let the user see if your script didn't find a file. Have a look at this http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors and http://www.php.net/manual/en/function.set-error-handler.php. The latter could be helpful, go through the page for examples. I suggest to log errors instead of displaying it. But that will involve some sort of workaround with code.
inform your developer that he should use __autoload or spl_autoload to avoid such errors…

Existing Class not found using XCache and PHP 5.3.2

I'm getting the weirdest problem using XCache and PHP 5.3.2 there is a class 'Vb_Post' that won't be loaded by PHP and throws a Fatal Error:
Fatal error: Class 'Vb_Post' not found in /Users/mario/Sites/m.techspot/app/models/Vb/Comments.php on line 5
If I run the same code with PHP 5.2 and XCache 1.2.2 or PHP 5.3.2 and APC everything runs fine. Is there a workaround/fix to this and does anyone know if this is a known issue, I've googled like crazy and haven't been able to come up with any solutions, I've read some people having similar issues using php 5.3.2 and APC but it looks like I'm suffering from the opposite.
I don't know exactly when this issue appeared but it worked fine until a week ago, and there were no major code change. The same problem happens in my development computer and on the server, both running the same mentioned software.
I'm pretty sure it has something to do with XCache since the first time it runs everything is OK, the error appears on subsequent requests.
Could it be that there's some hidden character that's causing this issue?
OK I found a work around for this problem. At the top of the Vb_Post class I was loading some classes that also referenced the Vb_Post class, apparently it was causing some kind of conflict that prevented the class from being loaded when cached.
The fix:
Moving the require_once('SomeClass.php') inside the class just before actually using it.
...
public function someAction()
{
require_once('SomeClass.php');
var $sc = new SomeClass();
...
}
...
So, after battling with these for about a week, this is the best solution I've come up with, hope this helps someone else.

Categories