I'm looking for a method to ignoring die() or exit functions.
Here is an example
Main file:
//Here some process
include 'seconfdile.php';
Second file:
//Some process
die();
//more process
Instead of die() use return in second file.
The die() in include/child file will kill the parent script execution as well.
So, its better to use return instead of die() it will terminate only child/include file not the parent file
Related
What is the reason why you need to use die(); to end ajax requests? I read that it's recommended to use die() or exit() to terminate the script when its sole purpose is meant for AJAX call?
Is this recommended for my script when the output is the very last thing in the script? Because my index.php file loads the environment, gets the content from controller then the very last thing is using echo to output the data. It's either JSON encoded data for ajax, or HTML content for non ajax. I could add the die at the end by checking if it's an ajax call, but I don't understand why I would need it here.
// index.php
// Load environment
require '../load.php';
// Handle request
$controller = new App\Controllers\Controller();
$content = $controller->doRequest();
// Output the content
echo $content;
// Terminate script with die() for AJAX requests (is this needed?)
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
die();
}
If you use one of those php-frameworks which can output additional data by themselves -- then you need to use exit
Also do not forget to DO NOT use ?> at the end of your script. You may leave empty line after php closing tag so your web-server will add this empty line to answer if you do not use exit
Also, do not forget about register_shutdown_function -- it will run immediatly after exit, so exit is the good way to prevent adding any other shutdown functions after echo $content;
You may not use exit in this concrete script, but also don't forget to remove ?> too
A child script terminates the parent script because it has exit;
Since it is a third party extension, I need to avoid any core hack. Would it be possible somehow to ignore the exit of the child script from parent script. I am calling its controller and a method from an external script.
parent.php
<?php
require "child.php";
?>
child.php
<?php
does something;
exit;
?>
Update
Any alternative solution would be fine as long as we dont modify the child script.
Is it possible to ignore exit from included script in PHP?
No.
exit terminates execution of the script regardless from where it is called.
As noted in sjagr's answer, there are alternatives to using exit.
If you do in fact end up editing the core files, then it is possible to use return inside of the "child script." From the PHP docs:
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.
However, there is no way to prevent the parent script from preventing a child script from killing the process if it has an exit statement. Unfortunately you cannot override this functionality.
You might be able to run child.php in a thread. Use join to wait until that thread finishes before continuing with the main thread. This way, calling exit in child.php will terminate the child thread and the main thread will continue.
class myThread extends Thread {
public function run(){
include "child.php";
//Call methods from child.php here
}
}
$thread = new myThread();
$thread->start();
$thread->join();
Thank you so much everyone for answering the question. Finally I came up with the following alternative idea. I am not sure if it is similar to any design pattern. The following example does not get terminated from loop although the child.php has exit.
parent.php
<?php
require "temp.php";
for($i=1;$i<10;$i++){
file_get_contents("http://url/temp.php?var=$i");
}
?>
temp.php
<?php
$var = $_GET['var'];
// execute
require "child.php";
$testController = new TestController();
$testController->method($var);
?>
Yes.
In your child.php you can use a return to return the control back to the parent.php.
Otherwise if child.php isn't included, it will continue with its normal operation, which is exit.
<?php
does something;
return;
exit;
?>
If you want to check whether a file was included or run directly, you could this answer.
So in that case, make a check in the child file, if it isn't included, goto the exit command, otherwise continue with the rest of the code.
Is there a way to use the die() function to stop executing PHP statements on a page included on another page, but continue the execution of PHP statements on the page on which the file containing the die() function was included?
use return; in your included file. It will stop this include execution. It works like a function. Also you can return a value from your included file
No. die is an alias for exit which immediately stops all script execution.
But you can use return instead, which does exactly what you want:
If called from the global scope, then execution of the current script file is ended. If the current script file was include()ed or require()ed, then control is passed back to the calling file. Furthermore, if the current script file was include()ed, 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.
As stated in the excerpt from the PHP docs, you can even use it to give a exit code / return value back from the include:
$include_retval = include('file_like_function.php');
if ($include_retval) {
die("include returned error code: " . $include_retval);
}
No. You could use try blocks instead?
try
{
include $file;
}
catch (Exception $e)
{
// Whatever
}
And throw an exception where you would use die() in $file.
In PHP, if I use the include() or require() functions to start running code in another script, is there a way to terminate the parent script from within the child?
So say I have this in parent.php:
require('child.php');
And this in child.php:
exit();
Will that terminate just child.php, or parent.php as well?
Is there a way to terminate parent.php from within child.php, without adding any further code to parent.php?
It's for an elaborate custom 404 error page in PHP which detects whether it's been called by Apache using ErrorDocument, or whether a user has requested a page from our custom CMS which doesn't exist. If it's the latter, then I want to just require my 404.php (child) and output from that and not continue executing the parent.
Anyone know if it's possible to terminate a parent PHP script from within an included/required script?
exit();
Will that terminate just child.php, or parent.php as well?
It will terminate the entire script.
If you don't want to do that, but return to the including script, you can return from within an include.
You are looking for return; command. This will terminate execution of only the child.php, and parent.php will be processed after that.
You can use return if you need to exist included file but continue from main script.
return
(PHP 4, PHP 5, PHP 7)
return returns program control to the calling module.Execution resumes at the expression following the called module's invocation.
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 also ends 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
Anyone know if it's possible to
terminate a parent PHP script from
within an included/required script?
You can use
die();
to end the furthur execution of any script at any point. Use of Die puts an end to the parent scripts as well.
die("End");
Will output "end".
Actually an exit; line in your child.php will terminate current php process that means parent.php will be terminated well.
You can also terminate an script by throwing an exception and catch it in one of the parent scripts.
This way you can control with precission which scripts to terminate and where to continue in the stack of "include / require" files.
die and exit will both terminate without prejudice. It is an application level command which cannot be caught or undone.
Using exit() will stop script execution and terminate the child and all parents.
You can try to throw an exception:
throw new Exception('An Error Ocurred');
I'm including file inner.php in outer.php, I have a condition in inner.php on which I want to stop executing inner.php but NOT the whole script, i.e. I want to jump to the first line in outer.php after the inclusion of inner.php, and I don't want to wrap all of the code in inner.php in an if statement.
Is there a way to do this otherwise?
Just do return; or return($value); on top level of the inner.php file.
If called from the global scope, then
execution of the current script file
is ended. If the current script file
was include()ed or require()ed, then
control is passed back to the calling
file. Furthermore, if the current
script file was include()ed, then the
value given to return() will be
returned as the value of the include()
call.
You can just call return in your include file, but if you're having to do this then it suggests there is something wrong with your architecture. For example, consider this include file:
<?php
// include.php
echo "This is my include";
return;
echo "This is after the include";
..included on the following page:
<?php
// index.php
include('include.php');
The output you'd get is: This is my include.
How about having two files for inner. The first and the second part and place the condition on the second include?
Throw an exception on the point where you want to stop
// in inner.php:
// ...some code...
throw new Exception('Error description');
// ...some code which will not always execute...
and catch it in the file where you want to resume
// in outer.php
try {
include 'inner.php';
} catch (Exception $e) {
//TODO: add error handling here
}
UPDATE
Unlike using return; as other answers here suggest, using exceptions will break anywhere, even if you're in some function inside inner.php