How to determine if this script was included into some other script - php

Some time ago, I developed a PHP script to send text messages, log sms usage, and so on. This is working fine.
Now I have modified it so that it may be included within another script via "include" or "require." Again it is working fine but I would like to make it operate slightly differently if "included" versus the command-line call. For example, if it's called from command line, then the parameters are in $argv, but if included in some function, we can assume certain necessary variables have already been set up, SQL connections are established, etc.
The point where I'm stuck, is trying to determine if this code is "include"d or is the main file. I know I can use get_included_files() to retrieve the necessary list. But at present (assuming my script is /path/myscript) the only test I know to use is something like:
$includes = get_included_files() ;
$isMainScript = ($includes[0] == '/path/myscript') ;
And therefore $isMainScript will be true if this was called from the command line. But clearly this is bad form; all one has to do to break it, is to rename the included script, or move it to some other directory. But I don't see any method of finding out the name of this file (/path/myscript) ... only the name of the main file (__FILE__ and its workalikes).
What do others do in order to determine if this script is a main script, or is subordinate to some other?

Related

PHP skips function call output

I have the following problem
require('drawchart.php');
if ( file_exists('drawchart.php')){ cwrapper();}
command using the 'chart.png' from cwrapper;
The cwrapper is a function inside the drawchart.php that accesses a MySQL and draws a Chart. This function works perfectly fine on its own and in a test.php but it stops producing the chart in my main program and I am baffled as to why it just won't work there.
I have tried introducing a sleep(30) to see if it needs to wait for the file to be written in order to succeed. But that doesn't help either. The 2nd command following just never picks up the output file chart.png. Directories are absolute paths in both cases so that's not a problem.
It does pick up an existing chart.png there but just not the updated one that should be generated from the if call. It seems to be skipping this call to cwrapper.
The cwrapper is using pchart to draw the chart And it does that perfectly on its own in a testscript.
How do I solve this problem?
Is there a better way to achieve this?
First of all, make sure the cwrapper() function is invoked.
Because you don't provide the path of drawchart.php, if it doesn't exist in the current directory, require() searches it in the paths specified in include_path in php.ini (it can be changed during the runtime).
file_exist() is not that lucky, it can find the file only if it exists in the current directory.
The best way to handle this situation is to not check if the file exists (who cares about it?, let require() handle it) but to check if the function you want to call exists:
require 'drawchart.php';
if (function_exists('cwrapper')) {
cwrapper();
}
In fact, because require terminates the script if the file cannot be loaded, you don't even need to check if the function exists. If it is defined in the required file then it exists after the require() statement returns (or the script is aborted otherwise).
Your code should be as simple as:
require 'drawchart.php';
cwrapper();

How to know if a script was included inside another script

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();

Manipulate PHP-Files before they are parsed

I have managed to write a small, compilable extension for php, that prints "test" on every ZEND_RINIT.
I tested it with an php-file that loads multiple other files, which again load others [...]. The problem is, that the extension just prints "test" once, so I assume it does not fire each time a new file is loaded, how can i get my extension to do so?
Also the event is fired before the file is loaded, that is what i want, but therefore zend_get_executed_filename() is empty and I am not able to get the file content...
My final goal is to validate each file before executing the script. I planned on doing so by validating a file signature that is appended to the file.
Pseudocode Validation:
decrypt(signature, rsa.pub) = sha(filecontent)
Pseudocode Signing:
signature = encrypt(sha(filecontent), rsa.priv)
file += signature
Or is there an even better way to validate the files (i want them to be signed) before executing the script in them?
Thanks in advance!
ZEND_RINIT is called on request startup, that is when you execute your php-file. It will never be called again during execution of your PHP file. Only on next startup.
You have to find a way to hook into all of the file load functions of PHP.

Using require_once inside a method

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.

passing URL variables to exec() with php

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;
}
}

Categories