I'm working on a PHP IRC Bot, and I'm currently working on the commands.
At the beginning of main.php, the script that starts the bot, it includes the class_lib.php file and instantiates the object of that class. I want to work on a !reload command, where it would "uninclude" the file and then reinclude it. Would that be possible, or would it be fine if I just included it again when that command was sent?
EDIT: Basically, I want to be able to modify and reload the class without having to restart the bot.
No, you can't. Revisit your design. Don't couple the definition of the class with the instantiation of the object.
Why not just allow the object to reload the default settings, or restart, instead of what you describe? I'm pretty sure you can't do that anyways.
Also, don't try to load the object with the class_lib.php. Include the class file with the object, then where and when you need it, create your object. That way you can stop it, destroy the object, and then re-instantiate another object, which should accomplish what you want.
Am afraid there is no way to uninclude a file. If it is a function, you could generate a new function dynamically each time.
Check:
http://php.net/manual/en/function.create-function.php
You can assign a function to a variable and then clear that variable and assign it again.
Late to the party, but I have to mention the following PHP-extension:
http://www.php.net/manual/en/book.runkit.php
The runkit extension provides means to modify constants, user-defined functions, and user-defined classes. It also provides for custom superglobal variables and embeddable sub-interpreters via sandboxing.
This would allow you to re-define classes, which happens upon parsing included files.
NOTE: I have not used this, I came upon it after researching if it was possible to somehow hotswap certain classes. I cannot vouch for the safety and can not supply hands-on info. Yet.
Late answer..
You could create an array containing the files and then eval(file_get_contents($filename))
I've been working on my own IRC Client named PITC and that may be the method I might use, It's how i've done stuff before
Related
I'm testing some database related functions in interactive mode.
The first thing I did is to include the testing file, let's say database.php
Then I can make change to the database by a function call.
The question is, when I make any changes to database.php, I have exit PHP interactive mode, re-enter, include the testing file again.
I'm seeking a way to reload the include file during the interactive mode.
There is no simple method of doing this cause PHP is not built for this job, but there are some things you can take a look at as it might do the job for you. However this all depends on what is in your database.php.
Create a simple function like reset and use PHP's runkit functions to update your include.
If your database.php contains functions, you need to remove the functions before including it again. If your file has a class defined in it you could try the import function and just call the function that does all this for you but in the end this is all manual labor and it might be simpler to look at other alternatives.
I for one use a auto refresh timer in my browser to refresh the page every # seconds. However I have two screens which makes using this method much easier.
That is something you should never do. It will create double functions, which will create confusion in the PhP interpreter.
You should require files out of your scope, so they are globally available, That way you can reduce the server overhead (memory usage) and reuse the included class directly without requiring it again.
Or you could create an autoloader, which imports the file when needed. If it is already there, it will return the needed instance without the extra overhead. An autoloader keeps track of the already included or required files.
That said, with include or required, you could load files. Instead of required_once or include_once, they keep including files.
I have searched and searched and found tons of examples but it seems that everyone has a different opinion about how and when to use session, some use it some say it is evil...
Here is my use case.
I have a Class that has several variables that will need to be used on every page in my application. These variables values are set by making a SOAP call to an API that I am working with. The SOAP call is relatively quick but I am trying to understand how to avoid making a call to the API on every page. I would much prefer to make the call once and then "store" the values somewhere.
I would think that I would just create an Instance of my class on some say Init.php page, make the SOAP calls and then store the whole class in session. Then on all of my pages include the Init.php page. In that page I would do a check to see if the Class existed in the session and if so then pull it form the session.
I know I have to serialize\deserialize the class to do this but I am looking for some feedback here on weather this is the right way to satisfy this use case or if there is a better option?
I am kinda new to PHP, mostly a .NET guys and in .NET the session is generally the best way forward.
All input is appreciated.
thanks
I assume when you stay "serialize\deserialize the class," you really mean you want to serialize/deserialize a class instance (an object) in the session, not the actual class definition. Be careful when using the terms class, instance, and object, since they are not interchangeable and can lead to confusion.
An object can be easily stored in a PHP session. PHP automatically serializes the object at the end of the request and deserializes it when the session data is read on the next request.
session_start();
if (!isset($_SESSION['soap'])) {
$_SESSION['soap'] = doSoapRequest(); // Returns an instance of your class.
}
When an object is serialized, only the variables defined in the class are saved along with the name of the class. When it is unserialized, the class definition must be available (that is, either autoloader or explicitly included into the script). Unserializing will create a class instance with the same data as the object that was previously serialized.
I'm relatively new to PHP, and I'm looking for a way to define certain objects as globally accessible from throughout the project, from multiple PHP scripts.
In Java, if I've to access some objects globally, I define some public class named Globals , and define the objects that I need to access as static in the Globals class. I then access those objects wherever I need with: Globals.variable_name .
So basically, I need to initialize these global objects only once and then use them whenever I need them..
One use case:
I've a class named Logger that has methods to log certain events in a log file. I need to have 1 Logger instance/object that can be used by all the PHP scripts in the project, whenever they've to log something. I'd rather not have each PHP script using it's own instance of Logger.
The naive Java-like approach I tried, that did not work:
I created a public class named Globals in a separate PHP file (named Globals.php) with one static object of type Logger, named $logHandle. I included this PHP file in all other PHP files where I need this Logger object. I then tried to access this object , using Globals->logHandle from one of the other PHP scripts. This attempt failed miserably.
Is there some similar approach?
Thanks.
PHP is not Java.
In web applications, the PHP environment is initialized for each request - and each request is handled in a different process with it's own memory space. It is possible to share access to data (including serialized objects, but not resources such as database connections and file handles) across different instances. You probably know this already but have not yet realised how it influences the way you write code.
I'd rather not have each PHP script using it's own instance of Logger
Why not?
One very good reason is that allowing multiple processes to write to the same open file handle requires locking to prevent the file getting all mesed up. BUT THIS IS PHP - STOP REINVENTING THINGS FROM SCRATCH. Writing to stderr will append the details to the webserver error log or use the OS syslog facilities - that's what they are there for.
It is impossible to have the same object available to all instances of PHP - you can unserialize an object in all instances - but then it's not the same object. You can run a daemon with a single object which might be accessible to all other PHP instances via a socket connection - but it's not running in the same address space.
If you validly have a class that you want to be universally available via an object with a fixed name, then simply create an instance of the object in each script or via an include file. The approach you tried is the way to go about this (but don't name your objects with reserved words). We don't know why it failed because you didn't provide any error messages or code.
I assume you're asking about common case (now only web-oriented application). And for that - no, you can not define some thing like you've described, in native way. This is the thing that is called superglobals in PHP.
But on the other hand - you need to do that for some reason, not "just because you want it". And, if so - then use configuration file. Create some application configuration file, read it once at start of application (bootstrap) and you'll get all needed values. I'm not saying anything about file structure - it can be xml/ini/yaml/whatever/you/like. But the idea is - to split this logic from application structure itself and use separate file for storing desired values.
Another option is to use some separate PHP file(s) and include it at bootstrap. Define all needed variables/constants in that file(s) and you'll get similar behavior. Note, that in terms of namespaces it's less "global" and you'll need to resolve all that cases manually.
For web-applications, however, one of possible solutions may be using sessions. $_SESSION is a superglobal array and it will behave like you want (i.e. will be accessible from everywhere). But that is not applicable always - and not always you'll want to deal with sessions to store session-independent data.
you can do like this
you said that you have included in all other classes change methods in your global class to static
<?php
class Logger {
public static function log($msg) {
// ...
}
}
you can use it like
Logger::log($msg);
http://www.php.net/manual/en/reserved.variables.globals.php
i think that is what you're after.
To access a static attribute in PHP you need to call it with the Class::$attribute notation, and the static methods need to be called with the Class::method() notation.
The -> notation is used when calling attributes of a class instance.
I was wondering if it is possible to hide variables from the "include". In other words, I want certain classes/variables which are declared inside a PHP file to basically not be visible to any other PHP file which includes it. Is this possible? Is there maybe a way around it?
Method 1: Separate those variable/class into yet another file, and call only the needed part of it. If you are going to use different part of the scripts in different context, place them in separate files and call them as you need it.
Method 2: After you include the file, unset the variables and destroy the classes.
IMHO, I think it's about time you get an introduction to PHP5 OOP.
Take a look at Visibility afterwards.
Your include file could define a function that does all the work, and the variables can be local to that function. As long as you don't declare them global they'll be gone when the function returns.
This function name will be visible to the caller, but it's better than having everything visible.
I have several classes which use static variables.
I assume that the classes are loaded into PHP when I include it in a php file being interpreted. Do I have to actively do anything to make sure that PHP does not 'unload' my class and I lose my static variables? Or does PHP simply never unload Classes once loaded? What if there's no file being interpreted at the current time? (I'm using php-cgi for my webserver)
Once loaded, they are not unloaded until the end of execution. Things do not persist over requests though.
static variable values within a class are set and retained within the context of a request only. If you want data to persist beyond the scope of the request, you have to use a session variable or write to a file or database.
No, all your request scope classes and variables will be available until the request is complete (or a call to a termination method is made, like die() or exit() as Corbin noted in the over answer).
If you use session variables then they will be available during the session is active.
To access a class or function, you simply need to make sure the file is included before you use it.