I was in charge of moving some domains from one server to another this week - and one of the sites pulled most of it’s data from a XML data feed, via SimpleXML. After syncing the entire site across to the new server, I was a bit worried to find that it had stopped functioning.
It was immediately obvious that the first problem was that the default PHP interpreter on the new box was PHP 4, and SimpleXML is a PHP 5 extension. Luckily, a PHP 5 interpreter was installed and the CGI handler was attached to a .php5 extension.
Rename multiple files on the command line (Linux + BSD, recurses sub-directories)
for i in `find ./ -type f -iname '*.php'`
do
j=${i}5
mv $i $j
done
Linux also has the rename command, which has the following syntax:
rename from to files
e.g. ‘rename .htm .html *.htm‘ will replace .htm with .html in all files matching *.htm.
The second part of this task is to fix all the broken require and include calls.
grep '\.php' -ZiRl * |
xargs -0 sed -i '' -e 's_\.php\([^5]\)_\.php5\1_g'
The grep arguments in order are: output a zero byte instead of the usual file seperator, case-insensitive matching, recursive, and only output the filename of files that match.
xargs is supplied with -0 to read zero byte seperated input, and then the sed command to execute.
sed’s arguments are -i ” to edit in place with no backup, and -e to execute the command string (can leave -e out on Linux, but BSD doesn’t like it). The command string is s for substitute .php5 for .php, but only where it’s not already .php5, and finally g for global substitution within the file.
Now the site was all running under PHP 5, but I was still getting strange results from SimpleXML. The XML was retrieving correctly, and looked like it was being parsed properly by simplexml_load_file, but on closer inspection I noticed that the returned objects were slightly different.
The old server (PHP 5.1.6) returned node attributes in a [@attributes] sub-array, and was accessed in code by using $node[$i]->attributes()->attribute. After browsing the documentation and playing around, I realised that this method was not around in PHP 5.1.1 (the new server’s version).
To access attributes in both versions correctly, you can simply go:
$node[$i]['attribute']
Another grep/sed command later and I had fixed all that - but now only the first node in any given result was being accessed properly. Investigating further, I discovered that PHP 5.1.1 returns 1 for count($xml->node), whilst PHP 5.1.6 returns the correct number of nodes that are present.
To quickly fix this, I replaced all occurences of count() on an XML object, with mcount() and then defined the following function:
function mcount($object) {
if (get_class($object) == 'SimpleXMLElement') {
$i = 0;
foreach($object as $o) {
$i++;
} //foreach
return $i;
} else {
return count($object);
} //else
} //mcount
Disclaimer: sed giveth and taketh away - ensure you fully understand what the commands are doing, and check them yourself as I might’ve made typo’s. Also, it’s probably a good idea to make backups when recursively modifying an entire project tree - one wrong command and you’ve broken everything.








