Safely replacing a function call in PHP source code - php

How can I replace all occurrences of realpath calls with realpath_fixed calls in a PHP source code (safely without breaking it)?
I ended up with '#realpath(\s*)\((.+)\)#' but onestly i don't know if this will work all the time.
EDIT: I can't edit the source code (deps not under my control) and this should be done in a PHP script while builing a PHAR archive.
<?php
foreach (glob(__DIR__.'/test/*.php') as $pathname) {
$contents = preg_replace(
'#realpath(\s*)\((.+)\)#',
'realpath_fixed$1($2)',
file_get_contents($pathname)
);
}

this should be done in a PHP script before packing all source files in a phar archive.
Then you do this wrong. If for any reason you need some methods substituted, you should wrap them in own implementation i.e. instead of realpath() you use myrealpath() in all the sources. And when you are about to release and need realpath working differently, then you just swap one file that implements myrealpath() and phar it. That's it.
EDIT
Of course but i can't replace realpath in 3rd party code.
Thta's changes things a bit. If you control environment you scripts run at, then you may consider using APD extension which offers rename_function() or runkit and its runkit_function_redefine().
If not, then I'd check how many realpath()s is in 3rd party libraries. If not that many and they do not change that often, then I'd probably craft patched version of these libs to use my myrealpath() instead. I still see this safer than global automated source search/replace.
EDIT 2
https://bugs.php.net/bug.php?id=52769
So it's all about phar. Maybe you shall just consider simply abandoning phar and distribute your code as regular composer package instead? Composer can deal with many type of repositories (i.e. zip file), so you do not have to push your code to packagist if it is proprietary.

Related

Dependencies graph for large PHP application

I've recently inherited a large PHP application with NO objects/modules/namespaces...only a lot of files containing functions.
Of course, there is a LOT of dependencies (and all files and almost always included).
I'm looking for a tool that could analyse the files and generate a dependencies graph. It would then be easier to detect independent files/set of files and re-factor the whole thing.
So far the best solution I've found would be to write a CodeSniffer sniff to detect all functions calls and then use that to generate the graph.
It seems something useful for other, so I'm sure tools already exists for it.
What would you recommend ?
I think that the best solution is use a doc generat + grapviz, PHPDocumentor looks to have a Grapviz extension at https://github.com/phpDocumentor/GraphViz
This is a example made with PHPDocumentor:
http://demo.phpdoc.org/Clean/graphs/classes.svg
Too you can use a hierarchical profiler like xhprof (https://github.com/facebook/xhprof), this can draw a tree of all call to functions from a execution.
A example form xhprof draw done by Graphviz
I could recommend a lightweight project I wrote few days ago. Basically I had a 300+ files PHP project and I wanted to detect what files do these files require/include and vice-versa. Moreover, I wanted to check for each individual file what files does this file requires/includes (directly or indirectly, ie. via file inheritance) and vice-versa: what are the files that include this particular file. For any combination of these I wanted an interactive dependency graph (base on file inclusion and not on class/function calls/usage).
Check out the project's sandbox and its source code.
Note that the whole thing was written in only 2 days so don't judge it
too harsh. What's important is that it's doing its job!

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.

Put PHP files toghether

Is there a tool to take a PHP file, with all its dependencies to other external PHP files, and create one, huge, final PHP file that includes them all?
Thanks
You don't really want to take a whole library and put it in a single file, because you end up loading a bunch of class definitions that might not even be needed by your script (i.e.: script A might need it, but not script B, however they end up loading it anyway).
PHP 5.3 (and a PECL extension for 5.2) introduced PHARs (PHP Archives), which works a little like JARs (Java equivalent):
$phar = new Phar('myLibrary.phar');
$phar->addFile('myClass.php');
Then you can do:
include_once('phar://myLibrary.phar/myClass.php');
I use it often and it is indeed very useful for quick software updates on client/production servers.
I've never heard of anything like that before, but maybe this could help... not really sure how it works http://webscripts.softpedia.com/script/PHP-Clases/Split-and-merge-files-19891.html
It is a new extension built-in PHP 5.3. You can read more about it here
http://www.php.net/manual/en/intro.phar.php

What is faster - using PEAR package or including required libraries directly into php code?

What will work faster - using PEAR package or require Some_Library.php files in code?
For example, what is faster - using Smarty as PEAR module or using require_once("Smarty.php")? Have anyone tested this?
Thank you
Both will be loaded from the include paths. The include path that comes first will be slighty faster, but I highly doubt you will notice a difference. You could do a benchmark though if you want to have numbers.
Basically, it works like this:
If you got a copy of Smarty in e.g. /var/www/app/libs/Smarty and another copy of it in PEAR and your include path is something like include_path="/var/www/app/libs:/php/pear" and you do a require 'Smarty.php', then PHP will first search in libs and immediately find Smarty. But without a local copy, PHP would still search the first include path, before it would search in PEAR, so it's a tiny (microseconds) bit slower. Nothing to worry about, unless you got many include paths. And of course, it depends on how you include paths are setup anyway. If PEAR comes first, then PHP will always search in there first. And if you use an absolute or relative path in require, the include path will be ignored altogether.
See the documentation for include and include_path for further details.
It doesn't matter at all when it comes to performance.
PEAR does nothing special with the libs. In the end they are just included as usual.
PEAR just provides a comfortable way for installation and dependency tracking.

Merging multiple PHP script into a single file

I have a PHP script which includes one or two other libraries it depends on using the 'include' statement. To make it more easily portable, I would like to somehow 'compile' the script and the included libraries it into a single PHP script (in the same way that ack includes all its Perl dependencies in one file). Is there an easy way to do this in PHP?
Clarification: Compiling to a windows executable could be (part of) an acceptable solution, but the script still needs to run on *nix, where it is better to have PHP source code with '#!/usr/bin/env php' at the top.
I want to be able to drop a single file into the $PATH somewhere on any OS and have it work without needing extra PHP libraries to be installed as well.
Newer versions of PHP support a concept similar to jar files in java. Take a look at phar. You could package all of your application files into a single archive and run that.
The PHP packages ScriptJoiner or even better JuggleCode might help:
http://packagist.org/packages/codeless/scriptjoiner
http://packagist.org/packages/codeless/jugglecode
Both are built upon PHP-Parser (http://packagist.org/packages/nikic/php-parser), which makes it very easy to join scriptfiles.
There's no built in way to do that. I would recommend packaging your code up into a directory and distributing it that way. I do this with PHP, I place the code into a directory "something.module", and then have iterate through a modules directory, including the main file underneath each .module directory. But for something more simple, you could just have a structure like:
my_package/
my_package.php
include1.php
include2.php
my_package.php would include(realpath(dirname(__FILE__).'/inclue1.php')). All other scrits would just have to include('my_packahe/my_package.php')
Manually, you just remove all references of include/require, and "concatenate" the files together.
you should also strip the open and end tags ('<?php', "?>") before concatenation, and add them in the final file.
For one or two small libraries, it should - hopefully - "just work"...
phc allows this. Just run it with the --include flag, and it will combine all your code (well, every argument to an include, require, etc) into a single PHP file.
If you like, it can also compile it, but that's not required to combine them all into a single file.
You could write a custom script that opens all the files, removes the opening and closing tags, and concatenates them together and saves as one file. should be pretty easy to do.
Or you can use a php compiler. It will do a bit more than what you are looking for, but if you just want one file, you run your dev project through one of these.
http://www.phpcompiler.org/
http://www.roadsend.com/home/index.php?pageID=compiler
You might also be able to use the built in php bytecode compiler to compile everything to byte-code and stick it in one file.
http://us.php.net/bcompiler

Categories