Does anyone here know when PHP executes include and include_once calls?
I'm wondering because I come from a Flash and Desktop development background where you have to import your classes at the beginning of each class.
But now that I am starting to build more complex PHP code, it seems like it would be better to just include classes when I actually need them to save on loading time. For example, look at the following psuedo code:
if (I_need_to_check_login)
{
include_once "Class.class.php";
$C = new Class();
}
If I do this, is the file Class.class.php going to be included everytime the code is run or only when I execute the include_once.
I'm a bit of a Class freak and usually build a class for just about any functionality used by my apps, so I often have lots of class files.
include, include_once are standard PHP instructions. This means the interpreter executes each include, include_once when he finds one in the flow of the program. If a control structure avoids to execute a piece of code which has an include instruction, this one won't be executed.
In your example, the include_once, will be executed if, and only if, I_need_to_check_login is true.
Includes are only performed if interpreter ever gets there. eg:
$variable = false;
if ($variable) {
include 'a.php';
} else {
include 'b.php';
}
In this case only b.php would be included.
For more on its behavior: PHP Manual - include
Yes, every time you have to call: $C = new Class(); you will have to require or include the file. Now what you can do instead of include_once is:
if (!class_exists('MyClass')) {
include("Class.class.php");
}
which mean you might not have you include it again, if you already included it before. This will also improve performance since include is faster to execute than include_once.
Files are actually included only if you perform include_once command.
So if that I_need_to_check_login evaluates to false - file will not be included at all
It can be easily checked by yourself with adding echo "I've been included"; exit; to the first line of that file.
Related
I am using PHP Include:
<?php include 'file1.php'; ?>
i want to only include the first few lines of file1.php - is this possible?
If you really want to include (run as PHP), then just pull those lines out into a new file:
new.php:
<?php
// line 1
// line 2
And include it in both files:
existing.php and other.php:
<?php
include('new.php');
...
<?php
$return_from_inc = include('file1.php');
?>
file1.php
<?php
if ($x === 1) { return 'A'; }
else { return 'B'; }
//... return ("break") running script wherever you want to
?>
Depending on the content of those first lines, why don't you use PHP Functions?
file1.php
<?php
function what_i_want_to_include(){
//"First lines" content
}
}
existing.php
<?php
include('file1.php');
what_i_want_to_include();
?>
Using functions it's the simplest way to do it.
You can simply use return on the line of your choice and control will be sent back to the calling file.
If called from within a function, the return statement immediately ends execution of the current function, and returns its argument as the value of the function call. return will also end the execution of an eval() statement or script file.
If called from the global scope, then execution of the current script file is ended. If the current script file was included or required, then control is passed back to the calling file. Furthermore, if the current script file was included, then the value given to return will be returned as the value of the include call. If return is called from within the main script file, then script execution ends. If the current script file was named by the auto_prepend_file or auto_append_file configuration options in php.ini, then that script file's execution is ended.
Source: PHP Manual
There are a few options to achieve this, but let me stress out that if this is necessary for your application to work you should really consider reviewing the app design.
If you want it programatically you can either grab the first x lines and use eval() to parse them. Example:
$file_location = '/path/to/file.php';
$number_of_lines = 5; //
$file_array = file($file_location);
if(!$file) {
return false; // file could not be read for some reason
}
$first_lines = array_slice($file_array, 0, $number_of_lines);
$to_be_evaluated = implode('', $first_lines);
eval($to_be_evaluated);
But you should take not that eval expects a string without the php opening tag (<?php), at least, not at the start. So you should search for it and delete it in the first line (if present):
if(strpos($first_lines[0], '<?php') !== false) {
$first_lines[0] = substr(strpos($first_lines[0], '<?php') + 5);
}
Another, and better option, and as suggested above, just pull out the required lines, save them to another file, and include them in both. You could also do this programatically, you could even extract the needed lines and save them to a temporary file on the fly.
Edit it is a 'weird' question, in the sense that it should not be necessary. Could you explain what exactly you are trying to do? Most probably we can come up with a nice alternative.
Edit
As I understand it correctly you have in the file-to-be-included a lot of stuff, but only the database settings are needed. In that case, put them elsewhere! Example:
settings.php
$connection = new mysqli($host, $user, $pass, $db);
if($connection->connect_error) {
die('This failed...');
}
header.php
<?php require_once('settings.php'); ?>
<html>
<head>
<title>My awesome website</title>
... other stuff
</head>
other_file.php
<?php
require_once('settings.php');
$r = $connection->query('SELECT * FROM `my_table` WHERE `random_field`=`random_value`');
etc. etc.
In settings.php you could also put everything in functions to ensure pieces are only executed when needed. You could in example create a get_connection() function, which checks if a database connection exists, otherwise creates it and returns it for usage.
No need for fancy eval() functions at all!
Please bear in mind that it isn't a crime to divide your application in a thousand files. It really isn't!
I've read that one of the differences between include and require is that
while include only includes the included file if the include statement is
encountered, require includes the file into the file hosting the require
statement even when the require code is not reached by the execution flow.
How can this have any implications. After all, if I have a file which says:
<?php
echo __LINE__;
?>
the output will always be 3, instead of printing the line inside at the
position inside the file which includes such include file.
This is simply not true, as far as I know. If the require line is not reached in the code, the file will certainly not be included.
The PHP Manual on require states:
require is identical to include except upon failure it will also
produce a fatal E_COMPILE_ERROR level error.
(emphasis on "except" added by me)
As far as I know, that's not how require works. The only practical difference is that require will cause your script to terminate if the file cannot be included, and include will just throw a warning and keep executing.
A very important idiom depends on your stated behavior not being true: conditional required files.
if(is_secure_page()) {
require "security.php";
}
Both require and include include their files at the point where they are reached in the execution flow.
A simple test case for this is:
if (false) {
require_once("Nonexistent.php");
}
echo "I'm doing SCIENCE and I'm still alive.\n";
Let's say you are running a mission critical application and will lose $1 per second. And some libraries are only used in certain case and are not affecting your business flow. You should probably use include_once for these optional libraries. Because if the file is not there require will stop your application from running with a fatal error.
require, or even better, require_once should be used exclusively when you want to include code that is actually required by the application, e.g. any libraries you need. include and its brother, include_once should only be used when the included file is not necessary to the execution of your script, such as when you are loading a sidebar or some tangental content.
The only real difference between the two statements is that is the file is not found, require with throw a fatal error, and include will just throw a warning and go on happily chugging away.
I believe that both require and include are loaded and parsed in exactly the same manner. If require would load a file in a given context, so would include.
I personally always use require_once, I find in most cases it's what you need (either you get the page once or you halt the script). And include throws warnings that you need to hide if you want to "try" including stuff. But that's just bad programming practice, a simple if (file_exists($file)) require_once $file; does the trick and totally beats include.
So in my opinion, require wins by far.
PS: Beaten by a sec !
I'd like to include the results of a given script (let's say a.php) into another script (let's say b.php).
Although there is the PHP include statement and their other counterparts (include_once, require and require_once), it seems all of them include the file contents instead of its processing results as I would expect.
So how can I get a.php processed first and then include its results (not the file contents itself) into b.php script ?
On the other hand, if my included file (a.php) has a return statement, is the entire file expected to be processed first or its contents are also included into b.php as is ?
Thanks in advance for your replies.
a.php:
<?php
echo "world";
b.php:
<?php
ob_start();
include("a.php");
$a= ob_get_clean();
echo "Hello, $a!";
perhaps?
Sounds like you want to use the backtick operator followed by eval.
Something like this:
$code = `/path/to/myscript.php`;
eval($code);
If myscript.php isn't executable you'll have to prefix it with php, as in:
$code = `php /path/to/myscript.php`;
Note that you need to completely trust myscript.php, otherwise this is an security problem.
This probably isn't a very good design, you might want to think hard about whether or not there's a better way to do what you want.
If a.php is accessible via the web, you could use file_get_contents with an http:// (or https://) URL. This will access your script like an ordinary web page, having your web server process it through PHP and return the results.
a.php:
<?php
echo 2+2;
b.php:
<?php
echo file_get_contents('http://example.com/a.php');
Output:
4
You can also use output buffering, as mentioned in DaveRandom's comment above. That said, this is generally not exemplary application design. It's preferred to have code that will return the results you need rather than echo them. So maybe something like this:
a.php:
<?php
function calculateA()
{
return 2+2;
}
b.php:
<?php
include('a.php');
echo calculateA();
Output:
4
Edit: Several alternatives are nicely detailed on the include page in the PHP documentation.
Summary:
If php file belongs to your server:
ob_start();
$result = eval(file_get_contents('/path/to/your/script.php'));
ob_end_clean();
If not, but it's accessible via HTTP:
$result = file_get_contents('http://path.to/your/script.php');
file1.php and file2.php with die(); function.
include.php:
<? include 'file1.php';
include 'file2.php' ?>
file1.php
<? echo 'included'; die(); ?>
file2.php
<? echo 'not included'; die(); ?>
How can I include both files with die(); function?
Non-English Speakers:
You can provide your question in your native language as well, and somebody here may be able to translate it for you. Just make your best effort to ask in English, and add your native tongue below.
If you would like to test whether the includes happened successfully, you can test the return value of the include function itself:
// http://us3.php.net/manual/en/function.include.php Example #4
if ((include 'file1.php') != 'OK') {
die();
}
You may also consider require() instead of include() depending on your needs:
require() is identical to include() except upon failure it will also produce a fatal E_ERROR level error. In other words, it will halt the script whereas include() only emits a warning (E_WARNING) which allows the script to continue.
If I understand correctly what you are trying to do then unfortunately it isn't possible.
die(); will stop the script from executing at the point from where it is called.
Here is how to include a file, or die with a message if the include fails code sample.
(include('file.php')) || die('Failed to include file!');
if (!condition){
include_once('./inc/header.inc.php');
echo "Errormessage";
include_once('./inc/footer.inc.php');
die();
}
I hope this is what you wanted.
Just a minor improvement to LorenzoP's method:
(#include("file.php")) or die("Failed to include!");
// notice the # sign!
This way, you save yourself 2 ugly lines of php warning when inclusion fails. Otherwise I think this is truly the best way to handle failed includes. (Also, his answer should be the accepted one.)
If the execution of your included file is not dependent on the current file (no shared variables, functions, etc.), then use
file_get_contents('link_to_file.php');
instead of an include method. When you force the file to execute independently it will not make a effect in the script execution.
die() is just an exit with an error, you can't include files with it and I don't really understand why you want to. Could you provide more details as to what you're trying to accomplish?
Is the following example appropriate for PHP's require_once construct?
function foo( $param )
{
require_once "my_file.php" ;
//
// do something here
}
Or is it more appropriate to only have require_once constructs at the beginning of the file?
Even though the file being included is useful only in the context of the function, is it not better to have includes at the top for readability and maintainability?
It comes down to a matter of coding style and opinion. Personally I keep all my require_once statements at the very top of my files so I can easily see which files are included where, nothing worse then some buried include messing with your scripts. However, if you have several large required scripts that are only required for certain functions, then putting the require_once inside a function would be OK from a performance stand-point, just make sure to put a note at the top of the page.
<?php
//require_once "my_file.php" (see function foo)
function foo($param) {
require_once "my_file.php";
}
This is something of a religious debate.
PROS for require and include statements at the top of the file:
dependencies are clearly documented in a consistent reliable place.
increased readability/maintainability
OP code caching is simpler (although you could argue that this doesn't affect the developer directly)
CONS for require and include statements at the top of the file:
If you're doing some kind of dynamic runtime including (such as with __autoload()), a hardcoded statement at the top of the file is impossible.
If only one execution path in the code uses an include, having it included every time, unconditionally is a waste of resources.
long list of include or require statement is just noise the developer must scroll past when editing a file. Of course, a long list of dependencies can be viewed as a sign that the code should be broken up into smaller more focused pieces, so maybe you could spin this one as a PRO because it makes a code smell stand out.
If you don't want to load a file unless it's needed, look into autoloading - on newer PHP via spl_autoload_register().
Maybe you only need the included file in certain cases, and you'd like to avoid including it if you don't need it at all, if it's a big file. So, I guess you could go for a require_once only in one branch of an if - else statement.
When using require_once keep in mind that this is not some pre-processor directive. The require_once statements are executed when PHP runs the code and it only executes if the specific script has not already been included during the execution.
For example:
conf.php:
<?php
$maxAge = 40;
?>
myscript.php
<?php
function foo($age) {
require_once("conf.php");
if($age > $maxAge)
return "1";
else
return "0";
}
echo foo(30); // Echos 1
echo foo(30); // Echos 0
?>
The require_once is not executed on the second call to foo(..) since conf.php has already been included once.