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.
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'm using CFPropertyList from https://github.com/rodneyrehm/CFPropertyList for handling content I add with PHP.
It all worked fine, but now that all content is added my file has about 700KB which is not big but seems big enough to let Apache crash on trying to save a file.
child pid 1278 exit signal Segmentation fault
I see in CacheGrind that a lot of time in my application is taken by calls to CFPropertyList->import() and CFDictionary->toXML() so where could be the bottleneck there???
Am I making to many changes at once? Should I load() and save() inbetween changes more to avoid having too many changes saved at once?
Any clue?
I do not think that it's the size that makes problems but a bug in PHP. Segfaults occur only if there is a serious bug in PHP itself.
The next steps:
First, upgrade to the latest PHP version (5.3.6)
If it does not happen anymore, feel happy
It still happens:
Reproduce the issue with a PHP script no longer than 20 lines.
Report the issue to bugs.php.net
When you implement a searchNode() function in an document of unknown size, you should always use a "depth" parameter to avoid stepping down in the document and calling your function enormous times in a recursive loop.
Because that creates infinite loops that also cause a segfault in PHP which don't end in a fatal error or warning.
Anyone got a problem with php 5.2.12 getting a lot of " Maximum execution time" error when trying to include() files?
I can't seem to find the bug in php.net, but it's consistently giving us that error on numerous scripts.
Anyone can recommend solutions?
The same script runs on a few other servers with php 5.2 without any problems. So just to let you guys know it isn't a script problem.
This is much, much more likely to be a problem with your code rather than with a specific version of PHP. PHP by default has a maximum execution time of 30 seconds, which you can modify by calling set_time_limit() or adjusting your php.ini settings.
If you're not doing something that you expect to take a long time, then usually the cause of this error is an infinite loop somewhere in your code. I'd throw a debug_print_backtrace() and a couple of exit() calls into some key locations and try to figure out which file is giving you grief, and then take a closer look in there. Perhaps you're stuck in an infinite include() hierarchy, in which case you should be using include_once() for all your class and function library files.
I would check to make sure the same include isn't getting requested time and time again somehow. You might try include_once() just to see if it changes things for you. That isn't a solution so much as it's a potential temporary fix. You should find out what is causing this if indeed it is getting called over and over again.
If you have xdebug setup and an IDE that supports debugging this would be a great way to dig into the code.
Otherwise, can you try putting some output statements in the first line of the included file and in the line PROIR to calling the include. See what's going on ...
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?