It's not a rare thing for me to deploy PHP to a server, or move it from one server to another, and have it completely f开发者_运维技巧ail with database or cookie errors. I'd like to get better at avoiding these kinds of issues before they happen.
What are some potential portability problems in PHP, with regards to different servers, OS's, and PHP configurations, and how can they be worked around? Let's assume that I (unfortunately) have no control over the server environment, besides FTP. (I'll add one answer to get things started)
In reality, there are too many to list. The reason is that it's very hard to write an useful application with just the very core of php enabled (no extensions at all). So if you want it to be very portable, you'll need to be able to fallback to different extensions (for example, it should be able to use PDO, MySQL and MySQLi extensions if you're using a MySQL's database).
In reality, there are a ton of dependencies that you would need to check for. It's not practical to list them all here (not by a long shot). Even things as simple as including paths can be an issue if you're running on Windows or with Safe Mode enabled. And that doesn't even take into account the different possible ini settings.
Fortunately there is a reasonably simple solution. Use a framework. Most frameworks have fallback methods and can do things in multiple ways depending upon server configuration. There are tons of frameworks out there, so I won't get into specifics on which one I'd recommend. By using an abstraction layer, they are able to deal with multiple different possible configurations (another example is caching technology, with drivers for APC, Eacellerator, MySQL, XCache, Memcache, etc).
The only other thing you can do to really be 100% sure is to test. What I'd recommend is writing as many unit, integration and functionality tests as you can. Tools such as PHPUnit and Selenium can greatly help with this.
Once you've automated testing, I'd suggest using a Continuous Integration tool (Such as Hudson ) to automate the testing based on SVN commit. With it, you can set up multiple target platforms to test with. So you can run 10 or 15 different virtual servers, and test each commit against each configuration automatically (Hudson will manage this for you). That way, you know instantly (well, quickly anyway) whether or not your code works with each and every commit without needing to do anything else on your part.
It's not an easy problem to solve. But it is solvable with a little effort and some ingenuity.
The other reasonable thing you can do is to declare minimum requirements and check for them. So if you want MySQL support, check for it during install... The same can go with INI settings... Just list a minimum required configuration, and check for it. That way if someone comes up with an "unsupported platform", you don't need to worry since they will be told outright it won't work...
Best Of Luck...
Some servers are configured with magic quotes enabled (magic_quotes_gpc=1
in php.ini
), which automatically calls addslashes()
on $_GET
, $_POST
, $_COOKIE
, and $_REQUEST
. It was originally introduced to help beginners unknowningly write more secure code, but its use is now depreciated.
To simulate disabling this misfeature at runtime if it's enabled, run the following code before using any of the request vars (adapted from this comment):
function destroyTheMagic($array, $topLevel = true) {
$ret = array();
foreach($array as $key => $value) {
if(!$topLevel)
$key = stripslashes($key);
if(is_array($value))
$ret[$key] = destroyTheMagic($value, false);
else
$ret[$key] = stripslashes($value);
}
return $ret;
}
if(get_magic_quotes_qpc()) {
$_GET = destroyTheMagic($_GET);
$_POST = destroyTheMagic($_POST);
$_COOKIE = destroyTheMagic($_COOKIE);
$_REQUEST = destroyTheMagic($_REQUEST);
}
Magic quotes of course are a huge problem, but using a single php.ini file for all your deployments would be a good idea. That file can be found in /etc/php5 (or whatever version of PHP you are using). This would ensure that the configuration of PHP across all servers is the same (including magic quotes settings). Also, make sure you also check with the phpinfo() function to ensure you are using the same version of PHP across all servers. Also, make sure when you deploy PHP to a new server, you have a list of all the packages you installed such as MCrypt, PEAR, PECL Libraries, ImageMagick, etc..
精彩评论