OK, so I have searched around for long enough to finally post this one here. Sure enough, it has been asked before a zillion time...
What I have, is one file, which includes another. No magic here. The trouble is, the included file then includes another file, which... includes yet another... Yep, a pain. Actually it's all working quite nicely, except that I now wanted to read the URL of the original file in the last of the included files.
So I thought in the original file, file_1.php I just say
$var_foo = dirname(__FILE__);
or
$var_foo = $_SERVER['SCRIPT_NAME'];
and then read that value in the first include, file_2.php, passing it on like
$var_foo_2 = $var_foo;
then in file_3.php
$var_foo_3 = $var_foo_2
etc, until I arrive at the final file, file_4.php, where I'd like to know the exact value of the original file's URL. Passing it on the first level works OK, but then it gets lost somewhere along the way. Tried going GLOBAL in file_1 -- to no avail.
Since file_3 and file_4 must both execute to produce data, setting a breakpoint a la echo / exit to spoof the current value (if any) is no option. I can live without that particular value, but I just would like to have it -- for the fun of it... Any ideas how to accomplish this?
Your examples use filesystem paths, not "URLs";I am assuming the filepath of the parent file is what you actually want.
You don't need to "pass" the variable on each included page. It will automatically be available to the code on the new page.
(If it is not, you may not be in the right scope: e.g., if you're inside a class or function, you'll need to pass it deliberately or use some other method - global, maybe, or even define the filename as a constant instead of a variable.)
main script
$parent_filename = __FILE__;
// alternatively
// define( 'PARENT_FILENAME',__FILE__ );
include "other-file.php";
other-file.php
include "other-dir/somefile.php";
other-dir/somefile.php
print $parent_filename;
// alternatively
// print PARENT_FILENAME;
/* prints something like:
/path/to/main.php
*/
As mentioned before, the issue has been solved like so:
set variable before the first include
add variable to query string
Thanks all for the input, appreciated.
Related
I am new to PHP and very likely I am using the incorrect approach because I am not used to think like a PHP programmer.
I have some files that include other files as dependencies, these files need to have global code that will be executed if $_POST contains certain values, something like this
if (isset($_POST["SomeValue"]))
{
/* code goes here */
}
All the files will contain this code section, each one it's own code of course.
The problem is that since the files can be included in another one of these files, then the code section I describe is executed in every included file, even when I post trhough AJAX and explicitly use the URL of the script I want to POST to.
I tried using the $_SERVER array to try and guess which script was used for the post request, and even though it worked because it was the right script, it was the same script for every included file.
Question is:
Is there a way to know if the file was included into another file so I can test for that and skip the code that only execute if $_POST contains the required values?
Note: The files are generated using a python script which itself uses a c library that scans a database for it's tables and constraints, the c library is mine as well as the python script, they work very well and if there is a fix for a single file, obviously it only needs to be performed to the python script.
I tell the reader (potential answerer) about this because I think it makes it clear that I don't need a solution that works over the already existant files, because they can be re-generated.
From the sounds of it you could make some improvements on your code structure to completely avoid this problem. However, with the information given a simple flag variable should do the trick:
if (!isset($postCodeExecuted) && isset($_POST["SomeValue"]))
{
/* code goes here */
$postCodeExecuted = true;
}
This variable will be set in the global namespace and therefore it will be available from everywhere.
I solved the problem by doing this
$caller = str_replace($_SERVER["DOCUMENT_ROOT"], "", __FILE__);
if ($_SERVER["REQUEST_METHOD"] === "POST" and $caller === $_SERVER["PHP_SELF"])
performThisAction();
From what I understand using something like require_once will essentially copy and paste the code from one file into another, as if it was in the first file originally.
Meaning if I was to do something like this it would be valid
foo.php
<?php
require_once("bar.php");
?>
bar.php
<?php
print "Hello World!"
?>
running php foo.php will just output "Hello World!"
Now my question is, if I include require_once inside a method, will the file that is included be loaded when the script is loaded, or only when the method is called?.
And if it is only when the method is called, is there any benefit performance wise. Or would it be the same as if I had kept all the code into one big file.
I'm mainly asking as I've created an API file, which handles a large amount of calls, and I wan't to simplify the file. (I know I can do this just be creating separate classes, but I thought this would be good to know)
(Sorry if this has already been asked, I wasn't sure what to search for)
It will only include when the method is called, but have you looked at autoloading?
1) Only when the method is called.
2) I would imagine there's an intangible benefit to loading on the fly so the PHP interpreter doesn't have to parse extra code if it's not being used.
I usually use the include('bar.php'); i use it for when i use databvase information, i have a file called database.php with login info and when the file loads it calls it right up. I don't need to call up the function. It may not be the most effective and efficient but it works for me. You can also use include_once... include basically does what you want it to, it copies the code essencially..
As others have mentioned, yes, it's included just-in-time.
However, watch out for variable definitions (require()ing from a method will only allow access to local variables in that method's scope).
Keep in mind you can also return values (i.e. strings) from the included file, as well as buffer output with ob_start() etc.
So i have three files.
FILE 1 includes FILE 2 which includes FILE 3
FILE 1 needs to print VAR 1 which is defined in FILE 3
how would I do that?
Its not echoing out for me
file 1
<?php
if ($_GET["pg"]==false)
echo "<title>Socal Mods</title>";
else
echo $title_name;
?>
file 2
<?php
if ($_GET["pg"]==false)
include("home.php");
else
include("".$_GET["pg"].".php");
?>
file 3
<?php $title_name="<title>Socal Mods</title>" ?>
file 3 is being parsed into file 1 which is the display container, but the %title_name is not echoing
One thing first about how you access the GET variables. You check the value using $_GET["pg"] == false. Note that this expression will fail to do what you expect in a lot situations. In fact, the value will never be directly false. The only way it will equal to false if it is empty or unset (in which case you will also get a compiler warning, which you should avoid). Usually a safer way to check if the value was set is using isset( $_GET["pg"] ).
The next thing I want to address is a security problem you introduce. You use the GET value directly to include a file with that name. If I was a user with malicious intent, I could easily set the pg value to something, you usually wouldn't expect and which break your website in some way. You generally should avoid using data the user entered somehow (request parameters are user data), and make sure to sanitize them first. A good way to do this, when you plan to use the value as a base to which page you want to include, would be to have some kind of whitelist of acceptable/allowed values. Then you can check if the entered data is in that whitelist and if that is the case, include the correct page. Another simple way would be using a switch statement to simply go through all accepted cases.
Now finally, onto your problem: I'm not sure if this was just a mistake when you posted the code, but file 1 is missing the include of file 2. As such you will never include file 3, and of course the variable will never be set.
Another problem might be the usage of the GET value. If the value does not contain the exact filename (as in casing and no extra whitespace), then the file won't be found. It is a good idea to echo out the filename you want to include in file 2, just to check if you are making any mistakes. The whitelist as explained above would be another way to make sure that you are trying to include the correct file.
Finally, you should enable error reporting on your server, you can do that either in your server configuration, or by adding the following line to the top of your first file (i.e. file 1):
error_reporting( E_ALL );
That way you will get errors and warnings that will tell you if something unexpected happened at runtime, and you might see your mistake easier.
Old answer
In general it works like this:
File 1:
<?php
include 'file2.php';
echo $myVariable; // prints 'Hello World!'
?>
File 2:
<?php
include 'file3.php';
?>
File 3:
<?php
$myVariable = 'Hello World!';
?>
echo $title_name = "<title>Socal Mods</title>";
It means its echoing html, So "Socal Mods" will be seen in title bar instead of the body. I hope you are looking in the titlebar. And to use $title_name in file 1 which is available in file 3 you hv to include file3 in file1.
Is file 3 included in the script? And have you actually validated and confirmed that the file is included? If you change the include statements in your script into require statements, PHP will stop with an error if the file you are looking for does not exist.
There are many reasons why a file might not be found. If the file name contains uppercase letters and the request only contains lowercase letters, you will run into problems if the server uses a case sensitive file system.
Also you should sanitize user input before you use that to include files. You don't want me to be able to include any file anywhere on your server, do you?
Variabes have to be created, set and assigned a value before they can be echoed.
Most probably ( please show us some code ), your problem is not the file includes, but you are trying to echo your variable before it is assigned a value.
I have a dedicated server that I use to crunch lots of data. The way I have it now, I can open a script with a process ID like example.php?ex_pid=123 and just let it go. It downloads a small portion of data, processes it, then uploads it into a database then starts again.
Ideally, I would like to call example.php?ex_pid=123 directly and not by passing a variable to example.php like exec('./example.php'.' '.EscapeShellArg($variable)); to keep it from acting globally.
I don't care about the output, if it could execute in the background, that would be brilliant. The server is an Ubuntu distribution btw.
Is this even possible? If so, any help and examples would be more then appreciated.
You could do something like:
exec("./example.php '".addslashes(serialize($_GET))."');
And then in example.php do something like this:
count($_GET) == 0 && $_GET = unserialize(stripslashes($_SERVER['argv'][1]))
The main issue with that is that ?ex_pid is GET data which is generally associated with either including the file or accessing it through a browser. If you were including the file or accessing it from a web browser this would be trivial, but running it as CLI, your only option would be to pass it as an argument, unfortunately. You can pass it as ex_pid=123 and just parse that data, but it would still need to be passed as an argument but doing that you could use parse_str() to parse it.
Depending on what the script does, you could call lynx to call the actual page with the get data attached and generate a hash for an apikey required to make it run. Not sure if that is an option, but it is another way to do it how you want.
Hope that helps!
I had a real problem with this and couldn't get it to work running something like example.php?variable=1.
I could however get an individual file to run using the exec command, without the ?variable=1 at the end.
What I decided to do was dynamically change the contents of a template file , depending on the variables I wanted to send. This file is called template.php and contains all the code you would normally run as a $_GET. Instead of using $_GET, set the value of the variable right at the top. This line of code is then searched and replaced with any value you choose.
I then saved this new file and ran that instead.
In the following example I needed to change an SQL query - the template file has the line $sql="ENTER SQL CODE HERE";. I also needed to change the value of a a variable at the top.
The line in template.php is $myvar=999999; The code below changes these line in template.php to the new values.
//Get the base file to modify - template.php
$contents=file_get_contents("template.php");
$sql="SELECT * FROM mytable WHERE foo='".$bar."'";
$contents=str_replace("ENTER SQL CODE HERE",$sql,$contents);
//Another search
$contents=str_replace("999999",$bar,$contents);
$filename="run_standalone_code".$bar.".php";
//If the file doesnt't exist, create it
if(!file_exists($filename)){
file_put_contents($filename, $contents);
}
//Now run this file
$cmd="/usr/local/bin/php ".$filename." >/dev/null &";
exec($cmd);
I had completely forgotten about this question until #Andrew Waugh commented on it (and I got an email reminder).
Anyways, this question stemmed from a misunderstanding as to how the $argv array is communicated to the script when using CLI. You can pretty much use as many arguments as you need. The way I accomplish this now is like:
if (isset($argv)) {
switch ($argv[1]) {
case "a_distinguishing_name_goes_here":
$pid = $argv[2];
sample_function($pid);
break;
case "another_name_goes_here":
do_something_else($argv[2]);
break;
}
}
I really have read the other articles that cover this subject. But I seem to be in a slightly different position. I'm not using modrewrite (other articles).
I would like to 'include' a webpage its a 'Joomla php' generated page inside a php script. I'd hoped to make additions on the 'fly' without altering the original script. So I was going to 'precomplete' elements of the page by parasing the page once it was included I hadent wanted to hack the original script. To the point I can't include the file and its not because the path is wrong -
so
include ("/home/public_html/index.php"); this would work
include ("/home/public_html/index.php?option=com_k2&view=item&task=add"); this would not!
I've tried a variety of alternates, in phrasing, I can't use the direct route "http:etc..." since its a current php version so must be a reference to the same server. I tried relative, these work without the ?option=com_k2&view=item&task=add
It may be the simple answer that 'options' or variables can be passed.
Or that the include can't be used to 'wait' for a page to be generated - i.e. it will only return the html.
I'm not the biggest of coders but I've done alot more than this and I thought this was so basic.
this would work include ("/home/public_html/index.php?option=com_k2&view=item&task=add"); this would not!
And it never will: You are mixing a filesystem path with GET parameters, which can be passed only through the web server (utilizing a http:// call... But that, in turn, won't run the PHP code the way you want.)
You could set the variables beforehand:
$option = "com_k2";
$view = "item";
$task = "add";
include the file the normal way:
include ("/home/public_html/index.php");
this is assuming that you have access to the file, and can change the script to expect variables instead of GET parameters.