I'm writing a new PHP application against an existing database which has been designed rather poorly.
The older application has a custom Test class which has been instantiated and inserted in the database, then retrieved and unserialized, etc. Obviously poor design, but it's worked for them so far.
My new application needs to be able to deserialize these objects, so I copy-pasted the old class definition to the top of the file where I use unserialize, but I get this error:
The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "Test" of the object you are trying to operate on was loaded before unserialize() gets called or provide a __autoload() function to load the class definition
Since I've defined the class before I use it, I thought this would work. Is it a problem with namespaces? The old class definition had no namespace, but now it's in App\Foo\Bar. This is a Laravel project that uses autoloading.
Related
I serialized an object of PHP class in Laravel. Afterwards, I changed the class definition adding a new method and when I unserialize the old object and make a call to that newly implemented method, it works.
I wonder why and how?
Because serialization process keeps only state of the objects (fields) but not your methods with implementation.
I have a master class, DBAPI which contains all the interaction with the database. It's not singleton per se, but is designed to only be instantiated once as $DBAPI.
When I alter the database, I obviously have to add functions to DBAPI to let the site use the new functionality, however, since there are a lot of different actions that can be taken, instead of including everything in a single massive class file, I've split them out by functionality/permission level as traits, and the DBAPI class file is dynamically created by adding traits flagged based off of permission level (read only, read-write etc.). Since the only time the file needs to be created is when new traits are added, I only create the class file if it doesn't exist for that specific user permission level, otherwise I use the already generated file. (If there's a better way to do this I'm all ears).
The issue I'm running into now is that if I add some functions in a new trait, the previously generated classes are obviously not aware of it, and I don't find out about that until I try to use the function in the code somewhere and it fails. It's pointless to write wrappers around every single function call made to check if it is a function first- is there some way to get the DBAPI class to do some action if code attempts to access a method it can't find?
for example, if code calls some function $DBAPI->newfunction() $DBAPI handles the exception itself, running some code that will attempt to update itself, which will cause newfunction() to run if it can be found.
(N. B. This architecture has a really bad code smell. I'm sure there's a better way to do this.)
PHP classes can implement the __call magic method that is used when there is no matching method name.
function __call( $name, $arguments ) {
// Code to run...
}
Without using CodeIgniter I would normally just do;
require_once("object");
test = new object();
How would I go about doing this in CodeIgniter?
Edit: for example this class could be a video game object. It might be holding a number of variables, for example title, age,description etc. There would also be variable get/set methods for the above variables.
For example, I might use this class to help contain the information created by a database search.
Codeigniter uses the Singleton design pattern and most of your classes are loaded using the loader class (as needed, in a constructor, or in the autoload config file) and are then available via the Codeigniter Super Object $this->my_model. As Kai Qing noted, using a Model would typically entail:
// In the constructor, controller method, or autoload
$this->load->model('my_model');
// Then to use a method simply
$this->my_model->my_method();
In Codeigniter classes are more like utility classes to group like functionality. However, you can always use native PHP in Codeigniter to require a class and then instantiate your own objects.
I usually setup a initial class on a website called something like baseFrame, which holds all the basics functions. (MVC style)
Now, I realized I was having issues calling the baseFrame from classes called throughout the website (the baseFrame has a function called callClass, which I was using to include and running the new class that extends from the base. I realized that you can't call a extended class under a function, because it's unable to read the parent class.
So, I wrote a new script called "callfunction.php" which was not a class base it self, it was a straight function that called the extended class, which calls the baseFrame correctly. Now this method worked, I however am not used to not using classes. Is there something I'm missing? Would I rather call a new class from within the baseFrame class? Is that possible? Again, running a class within the baseFrame class didn't allow me to call the extended at all...So I'm guessing that isn't technically possible?
may be this resources help.
there are many frameworks to build secure and reliable systems.
note: mvc is just one solution.
http://framework.zend.com/
http://wordpress.com (extensible via plugins)
http://www.codeigniter.com/
I’m fairly new to CodeIgniter and have a question. I’m a bit confused about Classes, Libraries and Objects.
Does CodeIgniter replace the normal PHP way of usings objects i.e. $var = new car(); with libraries i.e. $this->load->library('some_library'); $this->some_library->some_function(); ?
If both are valid, is there a difference? If so, what are the differences and when do I use one over the other? Which is more common/proper?
I am asking because I created a class, but I'm not certain what is the correct manner in which to instantiate it.
Thanks in advance
I am not familiar with CodeIgnitier. But familiar with other PHP frameworks. Most of frameworks use this way for performance improvements, registering things, executing certain events, and making things simpler for developer...
For example if you want to create class "car" with is somewhere in library directory you would have to include the file first before you can create object of that class (miltiple lines of code, more room for error). The framework will create the class and includes related files in 1 line of code (easier and safer).
Framework way also works as a factory. Instead of recreating an object, it will create object only once and every time you call the method again it will return the reference to existing object.
More things are happening behind the scenes when you use framework. Things are getting registered, etc...
CI doesn't replace class behavior per se, it simply adds functionality that allows access to custom libraries/models/views as singleton objects via the core object for simplicity.
Nothing is stopping you from creating (as I have in one of my projects) additional files with classes for non-singleton entities and require them in a model for further use. On hindsight, I should probably have used helpers for this.
What the loader ($this->load) class does, among other things, is it creates a single object of the specified class (model, library or view - not helpers though, see below) and attaches it as a property of the core class that is normally accessible via $this.
Helpers are a bit different. They are not attached, but instead simply 'read' into the global namespace from the point where they are loaded.
To answer your question, it would be more proper to use the loader class in instances where you don't need more than one instance of a class created. If you need 'entity' classes, your best CI-compliant bet would be to create them as helpers.
Given only this context, this looks like Inversion of Control (maybe I'm wrong, I haven't looked too closely at CodeIgniter).
You don't want to rely on the type car as in new car(). What if later you want to make $var a racecar? $var can still do the same things, but it is forced to be a car because you constructed it directly. Or what if you are testing this class, but car is some complex object which calls some external service. You want to test your logic, but don't care if the car service isn't working. So you should be able to change $var to actually load a mockcar. You can't do that if you do $var = new car().
What is Inversion of Control?