I have a really simple PHP script here,which simply loads several libraries (6 or 7 small classes) and initialize some variables then generate a very small amount of html code. But seeing from the memory_get_usage() function, I see 1.21MB memory usage.
Is that normal or something is wrong?
If you want to see what is actually loaded up when you execute PHP use this: get_defined_vars
The reason PHP is consuming memory may not be your script at all but rather your PHP configuration and other extensions being loaded when php executes.
Depends on the libraries. All it takes is one snippet of code to load up your memory. Have you tried to run a code profiler?
Related
When is a PHP include file parsed? At startup, or during execution?
My web forms call a single php script. Depending on the arguements passed in the URL, a switch/case condition determines what the script will do. Each "case" within the switch has its own include files.
If include files are parsed during initial load, then my php script will take up more memory/time to process which leads me to believe having individual php files called from my web form is better, than having one which includes what it needs.
If include files are parsed when needed (thus, when a branch of the code reaches a specific case statement, that it then performs the include) it tells me my code will be reasonably conservative on memory.
So.... my question... When is a PHP include file parsed? At initial load, or during execution?
(note... I failed to find the answer here, and I have read http://php.net/manual/en/function.include.php)
Files are included if and when the include statement is reached at runtime. To very succinctly summarise what that means, the following file is never going to be included:
if (false) {
include 'foo.php';
}
Since you're concerned about memory usage from too many includes, I feel that a bit more detail will be useful over and above a direct answer to your question.
Firstly, to directly answer you, PHP files are parsed as soon as they are loaded -- if a file contains a syntax error, you will be told of that immediately; it won't wait till it gets to that line of code. However subsequent files are only included if the specific line of code containing the include statement is executed.
You're concerned about memory usage, but having a lot of included files is generally not a major memory issue, nor a major performance issue. Indeed, most modern PHP applications of any size will use a framework library that load hundreds of PHP files for every page load. Memory and performance issues are far more likely to be caused by bugs within your code rather than simply loading too much code.
If you are concerned about memory and performance from this, you should consider using PHP's OpCache feature. With this feature enabled, PHP stores a cache in memory of the compiled state of all the files it has included within a system. When it runs the page again, therefore, it does not need to actually load or parse anything when it encounters an include statement; it simply fetches it from the cache.
Using OpCache you can write your code with a very large number of files to include, and without any performance penalty at all.
The good news is that OpCache is enabled by default in recent PHP versions, and is completely transparent to the developer -- you don't even need to know that it's there; the only difference you'll see between it being turned on and off is your site running faster.
So, firstly, make sure your PHP version is up-to-date (v5.5 or higher). Then make sure OpCache is enabled in your PHP.ini file. Then just sit back and stop worrying about these kinds of things.
File included with include statement are parsed during exection. When your php code hits a include statement it will start parsing the file to see what is in there.
From w3schools
The include (or require) statement takes all the text/code/markup that
exists in the specified file and copies it into the file that uses the
include statement.
There is other questions with a similar topic:
In PHP, how does include() exactly work?
I was always sure that the PHP functions file_get_contents and readfile execute any PHP code in any files - regardless of file type - that are given to it. I tried this on multiple setups, and it always worked.
I received a question regarding this here, and the user seems to think that this is not the case.
I looked at the PHP documentation for the functions, and they do not mention code execution (which is something that I would expect if this is normally the case, as it has serious security implications).
I also searched for it, and found a lot of claims that the functions do not execute PHP code. For example:
readfile does not execute the code on your server so there is no issue there. source
Searching for "php file_get_contents code execution" also returns various questions trying to execute the retrieved PHP code, which seems odd if it would indeed normally execute any given PHP code.
I also found one question that asks about not execution PHP code, so execution does seem to happen to others as well.
So my questions are:
do the functions file_get_contents and readfile execute PHP code in retrieved files?
does this depend on some php.ini setting? If so, what setting(s)?
does it depend on the PHP version, and if so, what versions are affected?
if it is not normally the case, what may be the reasons that they execute the PHP code in my setups?
file_get_contents and readfile do not execute code. All they do is return the raw contents of the file. That could be text, PHP code, binary (e.g. image files), or anything else. No interpretation of the files' contents is happening at all.
The only situation in which it may appear as if execution is happening is:
<?php ?> tags will likely be hidden by the browser because it's trying to interpret them as HTML tags, so this may lead to the impression that the PHP disappeared and hence may have been executed.
You're reading from a source which executes the code, e.g. when reading from http://example.com/foo.php. In this case the functions have the same effect as visiting those URLs in a web browser: the serving web server is executing the PHP code and returning the result, but file_get_contents merely gets that result and returns it.
Those functions are described in the «Function Reference / File System Related Extensions / Filesystem» section of the manual, while function to execute code are described at «Function Reference / Process Control Extensions».
I'm pretty sure the misunderstanding comes from a somehow widespread confusion between file system and network and that's made worse by the PHP streams feature that provides protocol wrappers which allow to use the same functions to transparently open any kind of resources: local files, networks resources, compressed archives, etc. I see endless posts here where someone does something like this:
file_get_contents('http://example.com/inc/database.inc.php');
... and wonders why he cannot see this database connection. And the answer is clear: you are not loading a file, you're fetching a URL. As a result, code inside database.inc.php gets effectively executed... though rather indirectly.
I would like to understand how the PHP compilation process works.
Assuming I have a file called funcs.php and this file has three functions, if I include or require it, will all the three functions be compiled during the file load? Or will the source code be read and kept in memory, until I call them and this call will trigger the compilation process?
Thanks,
Yes, all three functions will be read in and prepared for execution and their names will be saved into a table and from then on be reserved. So, syntax errors will also appear if you don't execute the function.
This process doesn't really consume much time, but you should try to reduce the amount of code and remove unused stuff. Mainly because it could cause problems after a major PHP upgrade.
I'm using DOMPDF to generate about 500 reports from one script. It's running out of memory after about 10-15 PDFs have been generated.
In debugging, it looks like it's loading 8M every time it gets to the font loading stuff, but this seems like something that should be handled with the font caching code.
Any ideas of what's going wrong here? I'd like to post a simple code snippet, but most of it is abstracted into multiple layers, so it's not just a simple copy/paste.
If you're using dompdf 0.6 beta, the memory error is the result of an infinite loop that dompdf enters when rendering tables. This is a known issue that I haven't been able to resolve.
Relevant URLs:
http://code.google.com/p/dompdf/issues/detail?id=34
http://code.google.com/p/dompdf/issues/detail?id=91
(The error you see is pdf PHP Fatal error: Allowed memory size of 268435456 bytes exhausted)
First if this is for anything remotely commercial just get Prince XML. It's substantially better and faster than any other HTML to PDF solution (and I've looked at them all). The cost will quickly be recouped in saved developer time.
Second, the quickest solution is probably to print each report in a separate process to solve any memory leak problems. If this is running from the command line have the outer loop be something like a shell script that will start a process for each report. If it's run from the Web fork a process for each script if you're on an OS that can do that.
Take a look at Convert HTML + CSS to PDF with PHP?.
As indicated by cletus, the quickest solution for you with DOMPDF is probably going to be rendering each report in a separate process. You can write a master script that calls a child script (using exec) which performs the actual rendering. As you can see in this discussion on the DOMPDF support group, it does seem to have the potential to provide a bit of a boost in performance.
It's difficult to say what's going on otherwise regarding memory usage without some kind of example that demonstrates the problem. I don't believe there is much optimization of DOMPDF and the underlaying CPDF rendering engine for multiple instances in a single script. So the font is probably being loaded into memory each time, even though it could use a static variable to cache that data.
My question is whether or not Flex's fcsh can be called from within a PHP script. Here is the background:
I have been created a simple process that creates a simple quiz/tutorial by converting a text file into a .mxml file and compiling to a .swf file using the mxmlc compiler. This works well from the command line, but I wanted to make the process easier by creating a web-interface to do this. My initial attempts with PHP's exec() function have not worked. The Python scripts I use to create the .mxml file work fine (using exec()), but I have not been able to get the mxmlc compiler to work.
After searching on the Web and on this site, I believe that using fcsh (instead of mxmlc) may be the way to go. Using fcsh would certainly compile the .mxml file faster (after the first run), and I think that fcsh can be launched as a service that might be able to be called from PHP.
On the other hand, maybe I am approaching this the wrong way. Would it be better to write a Flex application that calls fcsh and avoid using PHP?
Edit: Using fcshctl as hasseg suggested in his answer below worked very well. Thanks Ali.
The problem with calling fcsh from within scripts is that it works as an interactive shell instead of taking command-line arguments, compiling, and returning an exit status. There are different ways to get around this, which I've listed in this blog post of mine, where I mainly talk about fcshctl (which is my own solution for this,) but at the bottom of the post I've also listed other similar solutions to get fcsh integrated into nonstandard build workflows.
There are a few other ways in php to execute an external script. They are exec(), passthru(), system(), and backticks i.e. the key to the left of the 1 key. Each one has a different purpose and return mechanism.
You may have to put the command that executes your executable into a script and call that script via one of these functions.
Is there a particular reason why you can't use mxmlc directly? It seems like it would be easier to call than fcsh. Just specify all your compiler options in a XML file run it like mxmlc -load-config path/to/config.xml. You can find an example of the XML configuration format in FLEX_HOME/frameworks/flex-config.xml.