Is there a way to overwrite defines from different files? - php

I'm trying to make an interface for updating all instances of a WordPress plugin on a server that hosts 20+ WordPress sites. I've got everything working except for the fact that I have a loop with:
require_once($path.'/wp-load.php');
require_once($path.'/wp-admin/includes/admin.php');
require_once($path.'/wp-admin/includes/class-wp-upgrader.php');
where $path is equal to a website directory ($path changes with every iteration of my loop).
The reason I need to require the files this way is because wp-load.php includes (among other things) a file called wp-config.php, which defines things like the SQL database, which is different between each website.
TL&DR and stating my actual question:
Is there any way for me to do something like the following code?
require_once("dir1/a.php"); // define("VAR","dir1");
echo VAR; // displays "dir1"
unrequire_once("dir1/a.php");
require_once("dir2/a.php"); // define("VAR","dir2");
echo VAR; // displays "dir2"

Since you've mentioned this is an in-house tool, you could consider using runkit in order to remove the constant at runtime, allowing it to be redefined later: http://www.php.net/manual/en/function.runkit-constant-remove.php
Afraid not - even if you could, you wouldn't get the behaviour you're looking for because constants (define) can only be created once, and are like that for the rest of execution. They cannot be removed, or changed thereafter.
Unfortunately, you're going to have to re-architect your script (e.g. to use variables instead of constants).

Yes: fork the process. You can do something like:
foreach ($pathlist as $path) {
$pid = pcntl_fork();
if(!$pid) {
require_once($path.'/wp-load.php');
require_once($path.'/wp-admin/includes/admin.php');
break;
}
}
This will create a copy of your script for each $path in your list and gets around the require_once problem.
You need to "break" the loop if it's a child, as you only want the child process to run for its individual $path setting and not continue the loop itself!

Related

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

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?

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

Is it possible to dynamically reload PHP code while script is running?

I'm having a multiplayer server that's using PHPSockets, and thus is written entirely in PHP.
Currently, whenever I'm making any changes to the PHP server-script I have to kill the script and then start it over again. This means that any users online is disconnected (normally not a problem because there aren't so many at the moment).
Now I am rewriting the server-script to use custom PHP classes and sorten things up a little bit (you don't want to know how nasty it looks today). Today I was thinking: "Shouldn't it be possible to make changes to the php source without having to restart the whole script?".
For example, I'm planning on having a main.php file that is including user.php which contains the class MyUser and game.php which contains the class MyGame. Now let's say that I would like to make a change to user.php and "reload" the server so that the changes to user.php goes into effect, without disconnecting any online users?
I tried to find other questions that answered this, the closest I got is this question: Modifying a running script and having it reload without killing it (php) , which however doesn't seem to solve the disconnection of online users.
UPDATE
My own solutions to this were:
At special occations, include the file external.php, which can access a few variables and use them however it'd like. When doing this, I had to make sure that there were no errors in the code as the whole server would crash if I tried accessing a method that did not exist.
Rewrite the whole thing to Java, which gave me the possibility of adding a plugin system using dynamic class reloading. Works like a charm. Bye bye PHP.
Shouldn't it be possible to make changes to the php source without having to restart the whole script?
[...]
I'm planning on having a main.php file that is including user.php
which contains the class MyUser
In your case, you can't. Classes can only be defined once within a running script. You would need to restart the script to have those classes redefined.
I am not too familiar with PHP but I would assume that a process is created to run the script, in doing so it copies the instructions needed to run the program and begins execution on the CPU, during this, if you were to "update" the instructions, you'd need to kill the process ultimate and restart it. Includes are a fancy way of linking your classes and files together but ultimately the processor will have that information separate from where the file of them are stored and it is ultimately different until you restart the process.
I do not know of any system in which you can create code and actively edit it and see the changes while that code is being run. Most active programs require restart to reload new source code.
Runkit will allow you to add, remove, and redefine methods (among other things) at runtime. While you cannot change the defined properties of a class or its existing instances, it would allow you to change the behavior of those objects.
I don't recommend this as a permanent solution, but it might be useful during development. Eventually you'll want to store the game state to files, a database, Memcache, etc.
How about storing your User object into APC cache while your main script loads from the cache and checks every so often for new opcode.
To include a function in the cache, you must include the SuperClosure Class. An example would be:
if (!apc_exists('area')) {
// simple closure
// calculates area given length and width
$area = new SuperClosure(
function($length, $width) {
return $length * $width;
}
);
apc_store('area', $area);
echo 'Added closure to cache.';
} else {
$func = apc_fetch('area');
echo 'Retrieved closure from cache. ';
echo 'The area of a 6x5 polygon is: ' . $func(6,5);
}
See here for a tutorial on APC.
Simple solution use $MyUser instead of MyUser
require MyUserV1.php;
$MyUser = 'MyUserV1';
$oldUser = new $MyUser('your name');
//Some time after
require MyUserV2.php;
$MyUser = 'MyUserV2';
$newUser = new $MyUser('your name');
Every declared class stay in memory but become unused when the last MyUserV1 logout
you can make them inherit from an abstract class MyUser for using is_a
You cannot include again a file with the same class, but you can do so with an array. You can also convert from array to class, if you really need to do so. This only applies to data, though, not to behavior (methods).
I don't know much about these things with the games on PC but you can try to get all the variables from your database for the user and then update the text fields or buttons using those variables
In web is using AJAX (change data without refreshing the page).Isn't one for programming?

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.

How to know if php script is called via require_once()? [duplicate]

This question already has answers here:
Check if a file was included or loaded
(12 answers)
Closed 2 years ago.
My webapp has a buch of modules. Each module has a 'main' php script which loads submodules based on a query sent to the main module:
//file: clientes.php
//check for valid user...
//import CSS and JS...
switch( $_GET["action"] )
{
case "lista" : require_once("clientes.lista.php"); break;
case "listaDeudores" : require_once("clientes.listaDeudores.php"); break;
case "nuevo" : require_once("clientes.nuevo.php"); break;
case "detalles" : require_once("clientes.detalles.php"); break;
case "editar" : require_once("clientes.editar.php"); break;
default : echo "<h1>Error</h1><p>El sitio ha encontrado un error.</p>";
}
This main module deals with security and imports many resources all submodules need. The big problem shows up when a user asks for any of the submodules, bypassing all the security measures on the main module! My idea was to add a line on every submodule to test if it was being called directly and deny access or if its been called via another script, and continue. The least thing I would like to do is redo the security checking on every single file, since it does a bunch of query's to the database.
Does a php script know if its been called via a require_once() or a direct call ? I've been trying to implement some sort of $_SERVER['REQUEST_URI'] and $_SERVER['PHP_SELF'] pitfall but I was wondering if there was some sort of an elegant way of doing this.
I was looking for a way to determine if a file have been included or called directly, all from within the file. At some point in my quest I passed through this thread. Checking various other threads on this and other sites and pages from the PHP manual I got enlightened and came up with this piece of code:
if ( basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"]) ) {
echo "called directly";
}
else {
echo "included/required"
}
In essence it compares if the name of the current file (the one that could be included) is the same as the file that is beeing executed.
EXPLANATION:
__FILE__ is a PHP magic constant that stores the full path and filename of the file, the beauty of it is that if the file has been included or required it still returns the full path and filename of such file (the included file).
(Magic Constants Manual: http://php.net/manual/en/language.constants.predefined.php)
$_SERVER["SCRIPT_FILENAME"] returns the absolute pathname of the currently executing script. As when a file is included/required it's not executed (just included) it returns the path name of the (let's say) "parent" file (the one that includs the other file and the one that gets executed).
basename(string $path) is a function that returns the trailing name component of path, that in this case is the file name. You could also just compare the full path and filename, that would be indeed better, it isn't really neceseary to use this function but it feels cleaner this way, jajaj.
(basename(): http://php.net/manual/en/function.basename.php)
I know it's a "bit" late to be answering the main question but I guessed that it could be useful to anyone who's on the same situation that I was and that also passes by.
One elegant way is putting all your files which should only be accessed via include outside the web directory.
Say your web directory is /foo/www/, make an include directory /foo/includes and set this in your include_path:
$root = '/foo';
$webroot = $root.'/www'; // in case you need it on day
$lib = $root.'/includes';
// this add your library at the end of the current include_path
set_include_path(get_include_path() . PATH_SEPARATOR . $lib);
Then nobody will be able to access your libraries directly.
There's a lot of other things you could do (test a global variable is set, use only classes in libraries, etc) but this one is the most secure one. Every file which is not in your DocumentRoot cannot be accessed via an url,. But that does not mean PHP cannot get access to this file (check as well your open_basedir configuration if you have it not empty, to allow your include dir in it).
The only file you really need in your web directory is what we call the bootstrap (index.php), with a nice rewrite rule or a nice url managment you can limit all your requests on the application to this file, this will be a good starting point for security.
One popular method to make sure modules are not called directly is defining a constant in the main script, and checking for that constant in the module.
// index.php
define("LEGIT_REQUEST", true);
// in each module
if (!defined("LEGIT_REQUEST"))
die ("This module cannot be called directly.");
For the sake of completeness, the other possibility is to move such files to a directory that's not publicly available. However, some control panels used by hosting providers make this impossible. In such case, if you are using Apache you can place an .htaccess file inside the directory:
#
# Private directory
#
Order allow,deny
Deny from all
A common technique is to add this to the main module (before the includes)
define('TEST', true);
and to add something like that at the first line of every submodule
if (!defined('TEST')) {
die('Do not cheat.');
}
An alternative to defining a constant and checking it is to simply put the files that index.php includes outside of the document root area. That way the user can't directly access them via your web server at all. This is also obviously the most secure way, in case your web server has a configuration error in future that eg. displays PHP files as plain text.
You can define('SOMETHING', null) in clientes.php and then check if (!defined('SOMETHING')) die; in the modules.
global.php
if(!defined("in_myscript"))
{
die("Direct access forbidden.");
}
module.php
define("in_myscript", 1);
include("global.php");
A generic way that works without having to define a constant or use htaccess or use a specific directory structure or depend on the $_SERVER array that could theoretically be modified is to start each include-only (no direct access) file with this code:
<?php $inc = get_included_files(); if(basename(__FILE__) == basename($inc[0])) exit();
As practice of habit I have a console class built to send messages, errors, etc. to console with FirePHP. Inside the Console class write() method I have a check to see if a $_REQUEST[debug] == 1, that way I'm not exposing errors to users if something pops up on production and they would have to know what the request variable is to access the debug information.
At the top of every file I add:
Console::debug('fileName.php is loaded.');
here is a snippit from it to give you the right idea:
class Console{
public static function write($msg,$msg_type='info',$msg_label=''){
if(isset($_REQUEST['debug']) && $_REQUEST['debug'] == 'PANCAKE!'){
ob_start();
switch($msg_type){
case 'info':
FB::info($msg, $msg_label);
break;
case 'debug':
FB::info($msg, 'DEBUG')
break;
...
}
}
}
public static function debug($msg){
Console::write($msg, '');
}
}
Short and simple (for CLI):
if (__FILE__ == realpath($argv[0]))
main();

Categories