Is it okay to use chdir() in a shutdown function? - php

I noticed my Autoloader was not working properly on destructors (after die;), because PHP changes the current directory on shutting down.
was:
D:\www\arsenal
got changed to:
C:\wamp\bin\apache\Apache2.2.21
I don't even know why it does that. I solved the Autoloader problem using realpath but was wondering what kind of other problems it may cause.
So, is it safe to use chdir to change it back in a function registered with register_shutdown_function? I tested it and totally solved the Autoloader problem, as well as realpath did (the shutdown function gets called before the destructors, don't know why either).
The catch is that i'm afraid of the consequences. I don't even know if PHP behaves this way in other platforms. I would really like to have more information on the subject.
I'm on Windows 7, using WAMP 2.2 (PHP 5.3.8, Apache 2.2.21).

Related

PHP: getcwd() returns different results depending on server

I'm in the process of migrating a site from one server to another. On the old server, getcwd() returns the directory that the script is running, all of the time. On the new server, in one of my scripts, once it goes inside a function, getcwd() returns root. Outside the function though, it returns the correct directory. Could this be due to the different server APIs being used? (old server uses CGI/FastCGI, new on uses Apache 2.0 handler)
EDIT: I'm actually not relying on getcwd() in the code, but is_readable(). I'm just checking using getcwd() because I was told is_readable() (which isn't working) relies on the cwd
If you want to get the directory in which the current script resides, it's usually better to use dirname(realpath(__FILE__)) rather than getcwd().
__FILE__ is one of several "magic constants".
Yes, it could be due to a number of things, including differences in the way that Apache and PHP are installed, API used, PHP version, and OS. At least one of these things is not consistent from server to server. It's also possible (if not probable) that whatever is happening in the function in question is what's causing the change in behavior (though that wouldn't explain why that didn't happen on the old server).
You probably shouldn't rely on the output of getcwd() if you're going to deploy across several servers (or if you switch servers).
The behavior of your new server is odd, but I don't see why it would be a problem.
Ah, you didn't mention the switch from FastCGI to mod_php in your previous question! That's probably at fault -- Apache is starting in the root directory, while FastCGI does a directory change.
Have you considered just switching back to FastCGI? PHP 5.3.3+'s FPM SAPI is supposed to be pretty darn good, if you switched to mod_php because FastCGI was giving you trouble. (Edit: Ah, I see you've asked how in a different question. Unfortunately I've never set up FPM, only reaped the benefits...)
Otherwise the previous answers still apply: your code is far better off using __DIR__ or dirname(__FILE__) than relying on the cwd. Right now your code is broken by doing this. You've probably spent more effort trying to find a workaround than it'd take to just fix it by now. :)

Libraries other than ZipArchive for creating pkzip archives in PHP?

I'm in the process of writing some epub creation functionality using php5. Currently I am attempting to use ZipArchive but have run into a couple annoyances with it. First of all, there is no functionality to set the compression level. Second of all, ZipArchive::addFile() seems to fail silently and create a corrupt archive whenever I use it. I have been using file_get_contents() + ZipArchive::addFromString() instead but would prefer to just use the documented function for adding files.
I will not post code samples unless someone would really like to help me debug this issue, but rather I'm wondering if there are any other libraries for creating zip (pkzip) archives in PHP that you would recommend. So far, I have seen PclZip, whose site does not seem to be loading, but not much else. I have also considered using exec() + zip (unix command). This code will only run on this one particular linux box so portability is not an issue.
Thanks in advance for any suggestions!
PCLZip is pretty good alternative, with zlib as its only dependency, if you can get access to the site. It's probably temporary, it was certainly accessible between Christmas and New Year.
It's also pretty efficient, even in comparison with ZipArchive
EDIT
You say that you've had problems with ZipArchive's addFile() method. Is this in a Windows environment, or on your Linux server? I know that there have been a few buggy releases of the php_zip library on Win32 that can give this problem, although the latest versions seem OK, and I've not encountered the same problem on other platforms (even the WIN64 version).
I'd use exec() and the Unix command. A native-to-the-system way to solve the problem - the unix utils will always be a step or two ahead from their PEAR counterparts.

Did I find a bug in PHP's `crypt()`?

I think I may have found a bug in PHP's crypt() function under Windows.
However: I recognize that it's probably my fault. PHP is used by millions and worked on by thousands; my code is used by tens and worked on by me. (This argument is best explained on Coding Horror.)
So I'm asking for help: show me my fault. I've been trying to find it for a few days now, with no luck.
The setup
I'm using a Windows server installation with Apache 2.2.14 (Win32) and PHP 5.3.2. My development box runs Windows XP Professional; the 'production' server (this is an intranet setup) runs Windows Storage Server 2003. The problem happens on both.
I don't see anything in php.ini related to crypt(), but will happily answer questions about my config.
The problem
Several scripts in my PHP app occasionally hang: the page sits there on 'waiting for localhost' and never finishes. Each of these scripts uses crypt to hash a user's password before storing it in the database, or, in the case of the login page, to hash the entered password before comparing it to the version stored in the database.
Since the login page is the simplest, I focused on it for testing. I repeatedly logged in, and found that it would hang maybe 4 out of 10 times.
As an experiment, I changed the login page to use the plain text password and changed my password in the database to its plain text version. The page stopped hanging.
I saw that PHP's latest version lists this bugfix:
Fixed bug #51059 (crypt crashes when
invalid salt are [sic] given).
So I created a very simple test script, as follows, using the same salt given in an official example:
$foo = crypt('rasmuslerdorf','r1');
echo $foo;
This page, too, will hang, if I reload it like crazy. I only see it hanging in Chrome, but regardless of browser, the effect on Apache is the same.
Effect on Apache
When these pages hang, Apache's server-status page (which I explained here, regarding a different problem) increments the number of requests being processed and decrements the number of idle workers. The requests being processed almost all have a status of 'Sending Reply,' though sometimes for a moment they will show either 'Reading request' or 'keepalive (read).'
Eventually, Apache may crash. When it does, the Windows crash report looks like this:
szAppName: httpd.exe
szAppVer: 2.2.14.0
szModName: php5ts.dll
szModVer: 5.3.1.0 // OK, this report was before I upgraded to PHP 5.3.2,
// but that didn't fix it
offset: 00a2615
Is it my fault?
I'm tempted to file a bug report to PHP on this. The argument against it is, as stated above, that bugs are nearly always my fault.
However, my argument in favor of 'it's PHP's fault' is:
I'm using Windows, whereas most servers use Linux (I don't get to choose this), so the chances are greater that I've found an edge case
There was recently a bug with crypt(), so maybe it still has issues
I have made the simplest test case I can, and I still have the problem
Can anyone duplicate this? Can you suggest where I've gone wrong? Should I file the bug after all?
Thanks in advance for any help you may give.
The bugs 51059 (only about passing invalid inputs) or 50947 (not the same code, 5.3 has new algorithms and features implemented in php, on all platforms) are not related to this problem.
However http://bugs.php.net/bug.php?id=51424 is. I already posted a partial patch there, but it solves most of the possible locks but it is indeed not sufficient. A full fix will be present in the next 5.3 release.
By the way, it is not windows specific but about the threaded SAPI (windows apache 2.2 for example).
This question has now been viewed 128 times and upvoted 9 times. The only answer I've received says it's a bug, and points to one in the PHP bug database. I don't think it's exactly the same one, but it does seem to validate my diagnosis.
Therefore, with some hesitation, I have filed a bug report:
Bug #51666 - Using crypt() makes Apache hang or crash
Thanks to everyone who has looked at this with me - even if you didn't reply, just knowing that others were considering this with me, and not telling me I'm crazy, has been helpful.
Yes. It's a known bug,
http://bugs.php.net/bug.php?id=50947
You can simulate the crypt() result using mcrypt. If you can change your password hash, you should really use hash_hmac(), which is more secure and we have no issues with it On Apache. No experiences on Windows though.

Cannot redeclare class sfconfig

I am running Symfony (1.2.9) with PHP Version 5.2.11 on Windows XP.
I have APC installed (Version 3.0.19)
I can run PHP script to prove that apc is working correctly (works). However, when I try to use APC calls in a symfony action, I get this error (in the apache error.log file):
[apc-error] Cannot redeclare class sfconfig
Which promptly crashes Apache.
I tried using the Symfony sfAPCCache wrapper, and then directly calling the apc_* functions - the result is the same. Does anyone know why this is happening ?
Checkout these threads:
http://pecl.php.net/bugs/bug.php?id=16860
http://old.nabble.com/APC-under-WinXP-crashes-td25872662.html
Today this error happened to me, too, and I became aware of why it can happen (among possible other reasons).
APC correctly identifies every class by a fully qualified name, which includes the classes namespace. Unfortunately you can end up referring to the same class with various names.
For example:
I had a wrong "use" statement in my code, importing a non-namespaced class as if it had been inside a namespace.
The class, say "MyClass" was in namespace "\", meaning that its correct and fully qualified name was "\MyClass".
At some point the class was referred to by its unqualified name "MyClass", and got autoloaded. In another file I (wrongly) referred to the class with a namespace prefix in a use statement, say "use \SomeNamespace\MyClass;". Consequently the class was (again) passed to my global __autoload() method, but with a different name. To make it worse, the autoload method was smart enough to find the class anyway.
Instantly, my script stopped working and all that happened was APC writing "[apc-error] Cannot redeclare class ..." into the Apache Web Server error.log. My pages were no longer available.
This is not an APC bug whatsoever, but simply correct behaviour.
In my case it helped to temporarily disable APC (so that my script would be run regardless of the conflict), and hook an echo statement into my __autoload function producing a list of the parameters passed. The class loaded with a wrong name would show up quickly, and I could fix it and reenable APC.
Hope this helps someone.
Ive had this error before unrelated to APC and it always helped to not only run the cache:clear but also to check and make sure all files were deleted from the cache dir.
I was living the same situation on my development windows
system with php 5.2.11 and several apc versions. Same
situation as described, with stat=0 everything works, but
when I set stat=1, apache crashes with error "cannot
redeclare class [some class]". The code is working on a
different windows system, beside it is live on a heavily
loaded linux production server for months. I'm %100 sure
there is no bug related to apc. It started on my machine
after I reinstalled my OS.
I spent some time commenting out some class includes and
realized that it works with some include files but not with
specific ones. I checked my code there is no noticeable
difference on the class differences.
Then I saved all of my include files with adding some
additional whitespaces with Zend Studio's editor. It looks
stupid I know but it works!!! I'm working on the project
with several people and using svn and everybody uses
different text editors like notepad++, editplus etc...
However I couldn't reproduce the error by trying save the
file with some different editors with different configs like
ansi, utf8 with/without byte-mark ordering etc. But I'm sure
my problem is something related to file format (encoding,
pc/unix mode). I'd like to reproduce the error and want to
give more detailed info but I tried my solution on another
project with same problem, it works either.
I hope I could give another perspective to the issue.
What solved this for me was making sure my requires had the same path.
For example, the error I got was:
[apc-error] Cannot redeclare class someClass
In file A I had the following:
require_once '/path/to/someClass.php';
In file B which resides in the same directory as someClass.php I had the following:
require_once 'someClass.php';
I believe that APC caching didn't understand they were the same file because the path was specified for one and not the other.

Connection Interrupted. The connection to the server was reset while the page was loading

I am calling a PHP-Script belonging to a MySQL/PHP web application using FF3. I run XAMPP on localhost. All I get is this:
Connection Interrupted
The connection to the server was reset while the page was loading.
The network link was interrupted while negotiating a connection. Please try again.
There are a number of possible solutions ... depends on the "why" ... so it ends up being a bit of trial and error. On a fresh install, that's tricky to determine. But, if you made a recent "major" change that's a place to start looking - like modifying virtual hosts or adding/enabling XDebug.
Here's a list of things I've used/done/tried in the past
check for infinite loops ... in particular looping through a SQL fetch result which works 99% of the time except the 1% it doesn't. In one case, I was using the results of two previous queries as the upper and lower bounds of a for loop ... and occasionally got a upper bound of a UINT max ... har har har (vomit)
copying the ./php/libmysql.dll to the windows/system32 directory (Particularly if you see Parent: child process exited with status 3221225477 -- Restarting in your log files ... check out: http://www.java-samples.com/showtutorial.php?tutorialid=1050)
if you modify PHP's error_reporting at runtime ... in certain circumstances this can cause PHP to degenerate into an unstable state if, say, in your PHP code you modify the superglobals or fiddle around with other deep and personal background system variables (Nah, who would ever do such evil hackery? ahem)
if you convert your MySQL to something other than MyISAM or mysqli
There is a known bug with MySQL related to MyISAM, the UTF8 character set and indexes (http://bugs.mysql.com/bug.php?id=4541)
Solution is to use InnoDB dialect (eg sql set GLOBAL storage_engine='InnoDb';)
Doing that changes how new tables are created ... which might slightly alter the way results are returned to a fetch statement ... leading to an infinite loop, a malformed dataset, etc. (although this change should not hang the database itself)
Other helpful items are to ramp up the debug reporting for PHP and apache in their config files and restart the servers. The log files sometimes give a clue as to at least where the problem might reside. If it happens after your page content was finished it's more likely in the php settings. If it's during page construction, check your PHP code. Etc. etc.
Hope the above laundry list helps somebody someday ... probably myself when I run into it again and come back here looking for "how the heck did I fix it last time?" ... :)
It's possible that your script could be caught in an infinite loop. If that doesn't apply, then I'd check the error logs like TimB suggested.
It sounds like the PHP script you're calling is failing without returning a valid response. Depending on the level of logging that you have set up, this should generate an error in the Apache logfile, which will give you some idea of the problem. I'm not familiar with XAMPP, but you should be able to find out where the logs are, and look for an error that occurred at the time you made your request to the PHP script.
copying libmysql.dll to apache\bin folder may help you overcome this strange error
I solved this problem Upgrading the xampp\php\ext\xdebug\php_xdebug.dll
(changed to php xdebug v.2.0.5-5.3-vc9 )
I had the same problem and this is what i did.
I issued the http get command through php cli script, and as it turns out I had declared one class twice somewhere.
By the way , i use AMPPS on an mac
Hope this helps some one!
Try doing the request with Firebug enabled and see what info you can get out of that; I always find that using wget is helpful for seeing the raw HTTP interaction without worrying about Firefox's UI elements interfering.
If you are using certificates for ssl in Windows 2008 Server(iis 7) from old selfssl tool(iis 6), that is the problem. Sometimes Microsoft releases patches which can destruct all these old certificates. The solution is to generate them again.
copying libmysql.dll to apache\bin folder may help you overcome this strange error
Indeed this helped me to solve this problem
The connection to the server was reset while the page was loading.
Incase the issue is not working this did the trick for me.
1. I got a new zip directory for PHP and connected it with apache
2. I searched for the libmysql in the new php and inserted this to the apache/bin
its this libmysql.dll that is needed there and not the one form mySQL/bin.
ok at least thats the one that worked.
I experienced a very similar issue - which doesn't apply to the person who asked this question - but may be of help to others who are reading this page...
I had an issue where in certain cases PHP 5.4 + eAccelerator = connection reset. There was no error output in any log files, and it only happened on certain URLs, which made it difficult to diagnose. Turns out it only happened for certain PHP code / certain PHP files, and was due to some incompatibilities with specific PHP code and eAccelerator. Easiest solution was to disable eAccelerator for that specific site, by adding the following to .htaccess file
php_flag eaccelerator.enable 0
php_flag eaccelerator.optimizer 0
(or equivalent lines in php.ini):
eaccelerator.enable="0"
eaccelerator.optimizer="0"

Categories