(I'm starting this question over from scratch. If you want to know what the original question was that MrMook attempted to answer, or the revised question that Progman commented on, see the edit history. I have now boiled down the behavior to the barest elements and ask the question anew based on that.)
I have created five files and their entire contents are as follows:
test-forward.php
<?php
require_once('script1.php');
require_once('script2.php');
?>
test-backward.php
<?php
require_once('script2.php');
require_once('script1.php');
?>
script1.php
<?php
SayHello()
?>
script2.php
<?php
function SayHello() {echo 'Hello';}
?>
test-together.php
<?php
SayHello();
function SayHello() {echo 'Hello';}
?>
When I run either test-backward.php or test-together.php, the browser says Hello, and there is nothing added to PHP log file.
When I run test-forward.php, the browser is blank, and the PHP log file reports:
PHP Fatal error: Uncaught Error: Call to undefined function SayHello() in ...\script1.php:2
The script test-together.php shows that a function can be called before it is defined. My understanding is (as MrMook said) that included (or required) scripts are all merged into the script that includes them before the whole thing is processed as one. But if that is true, then test-forward.php should behave the same as test-together.php, but it is not. Instead, it appears that in test-forward.php, script2.php is not being read.
The code above is the full contents of the five files, so you should be able to reproduce this behavior on your system. I'm running PHP 7.2 under Windows 7.
Why is SayHello() not defined when running test-forward.php?
PHP checks the executet file for requried files and just add the content of the required file into the executet file.
For Example if you execute script0.php which contains two required_once. It will first merge the content of both required_once into script0.php and then compile it.
So your executet file will be:
function1();
exit();
function function1() {}
When a script is loaded with require or include the content gets executed at the time when the require or include statement is called. When the script is trying to access a function which isn't defined (yet), you will get the generated error message.
Related
I have 2 pages :
functions.php
function get_test($name) {
return 'Yo '.$name.' !';
}
test.php
include('http://www.exemple.com/functions.php');
echo get_test(Thomas);
When I execute my script on the server :
Fatal error: Call to undefined function get_test() in /htdocs/test.php on line 5
Note: I don't use Wordpress
Thanks
Don't do this:
include('http://www.exemple.com/functions.php');
It causes PHP to issue a full-blown HTTP request to your own server, causing Apache to EXECUTE that script, and return its output. That means you're not getting PHP code. You're getting the OUTPUT of that php code, which is not likely to be valid PHP code.
include/require via HTTP is almost always a sign of bad design, and also a major security vulnerability, if you're include/requiring from an actual remote url. Nothing says that the remote url can't return something like <?php system('rm -rf /'); ?>, which your server will then happily start executing.
Almost certainly you only need something like this:
include('functions.php');
I am trying to keep my PHP code on one server, while calling the functions from a separate server.
Server 1
<?php
echo 'Server 1';
function testingStuff(){
echo 'Testing Stuff';
}
function testingStuff2(){
return "Testing Stuff 2";
}
?>
Server 2
<?php
include 'fullURLtoServer1.php';
testingStuff();
echo testingStuff2();
?>
I know the include statement is working, as "Server 1" is being properly echoed to the screen, but neither of the function calls displays anything. Am I missing something? Why do neither function calls work?
EDIT 1
The ideal situation would be having a single .php file on Server 1 that contains multiple functions, which I can call as often as I'd like.
When you "include" a remote file, you are included the output of that file.
For server 2, the file you are trying to include just says:
Server 1
If you want to execute remote functions, you can make a different file for each function, and execute the function when the file is called. That way, you can "include" the remote file and show the output. You can replace the "different file for each function" for a single file with a parameter.
Keep in mind, trough, that any user/server/bot can call those functions by simply loading the file from the webserver.
I need to compile the php code on HTML Button click and display the compilation output on browser.I am using the following code to display the output on browser,it works well in terminal but doesn't give anything on browser.I am using XAMPP server on windows machine.
<?php
if(isset($_POST['compile'])){
$cmd="php php_part.php";
$var=system($cmd);
echo $var;
}
?>
<input type="submit" class="button" name="compile" value="Compile Code" />
First you are not compiling the php_part.php script, you are running it. Yes I realise that running a php script requires that it first be compiled or rather interpreted but that statement will execute the php_part.php script.
There are 2 likely reasons why it is not running.
When run from the browser i.e via Apache it does not know where to find php.exe
Depending on where the php_part.php script is kept it may not be able to find that either.
Try changing this statement
$cmd="php php_part.php";
to
$cmd="C:/path/to/php/php.exe C:/path/to/script/php_part.php";
If that works then that above was the problem.
I have to also say that there must be a better way of running this script. As you are in a PHP section of code would not a simple include or require not be a better solution. Something like this
<?php
if(isset($_POST['compile'])){
require "php php_part.php";
echo $var;
}
?>
Of course this depend on how you have written that php_part.php script. If you wrote it as a function then this would be a better solution
The php_part.php script
function xxx() {
// do whatever coding
return $the_result;
}
The main code
<?php
if(isset($_POST['compile'])){
require "php php_part.php";
$var = xxx();
}
?>
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.
I'm trying to include a remote file from one of LAN pcs using include, allow_url_fopen = On and allow_url_include = On.
One local PC (let's say pc2), I have remote.php, which contains:
<?php
echo $var_on_pc1; // this doesn't output
$remote_var = 'Var on pc2';
function square($num){
return $num * $num;
}
?>
In my PC (let's say pc1), I have test.php, which consists of this:
<?php
$var_on_pc1 = 'Var on pc1';
include "http://pc2/path/to/remote.php";
echo $remote_var; // this doesn't output
echo square(4); // this got error
?>
When I run the script test.php, i got the error:
"Fatal error: Call to undefined function: square() in
path/to/test.php on line 7.
What happened? I thought I could call the included functions and variables and vice versa?
If I cannot implement this, what is the best way?
I have no security concern because I use this locally for temporary development.
Type http://pc2/path/to/remote.php into your browser and see what you get. PHP gets exactly the same.
If the PHP file is being processed by the web server at pc2, you likely get zilch in that file, because the code as been processed. You'd need to configure the other server to not process the PHP file and serve its raw source code instead.
This is not a good idea overall.