1) Suppose I have 2 php files: fileA.php, and fileB.php
And I have 1 class file: myClassFile.php
in fileA.php, I need to instantiate a MyClass class in myClassFile.php:
...
myObject = new MyClass();
...
in fileB.php, I need to use the myObject object created in fileA.php.
How would I do that? Is using sessions the way to go?
$_SESSION["my_object"] = myObject;
or are there better ways? Specifically, how will it be implemented?
2) Suppose I don't use solutions similar to the above.. Will myObject in fileA.php be lost (destroyed, or freed) when the user proceeds to fileB.php? That is, will there be no more reference to myObject in fileB.php?
It sounds like you're doing something unnecessary complicated.
The information you passed and treated in MyClass has to be available somehow in the object.
Create a method to extract all these information to an array and save this array in a session. When reaching the next page, create an instance of MyClass again and feed the object in another method for this purpose with the information array from your session.
I am not an expert but if your object is like a configuration object which you need to access from many places then consider using Singleton pattern
Related
I want to research the source code of pyrocms, and when I read the Base.php, I can't understand the following code
new CI;
the file is system/cms/libraries/Base.php
My problems are
why there has no a variable name, like $CI = new CI;
why it can be used as CI::$APP->config->item('controller_suffix') in it's sub class MX_Controller since there does not have variable name?
Thank you very much!!!
This object isn't stored in a variable because it seems we don't need to manipulate it. On the other hand, look at its constructor: it does a lot of things (since it also calls the constructor of CI_Controller, which in turns loads a Loader and initializer it, ....)
So, we don't build it in order to manipulate it afterwards, but in order to run the code in its constructor.
We can use CI::$APP-> whatever because $APP is a static member, hence it doesn't require to have an instance of CI to be manipulated
Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static cannot be accessed with an instantiated class object (though a static method can).
see statics on php.net
Reading this documentation of the Silex PHP micro-framework,
In the section
The service will now be registered in the application, and the convert method will be used as
converter:
The code
$app['converter.user'] = $app->share(function () {
return new UserConverter();
});
$app->get('/user/{user}', function (User $user) {
// ...
})->convert('user', 'converter.user:convert');
$app is an array + an object at the same time. Or let's say it starts as an array but gets assigned an object. This confuses me: $app['converter.user'] =.
How does this work?
Using the PHP Iterator interface, as well as the ArrayAccess interface will allow PHP to know that your class can be treated as an array. One easy way to do this would be to extend from the ArrayObject class.
Essentially, what's happening with these interfaces is that you have a private variable, and methods on how to access that variable. The interfaces let PHP know that these methods exist, and that it can in fact treat the class as an array.
Now, if Silex uses this method or not, I can't comment. However, that is how you would create a PHP class that can also be accessed as an array
$app is not an array and an object. It is just an object, of which you can access the values through either the index or using the -> operator.
To answer your 2nd question, this is possible through overloading, which you can read here.
I have a class called Page, which loads a PHP file for the current page, containing all the HTML (template file). In my template file, I want to use instances of other objects, that is initialized outside the Page class (ex. User, PDO or other classes). My problem is, how I do this the smartest way.
In my page class i have a method called get_page() which loads my template file (containing all the code for my GUI.
public function get_page() {
// Load theme template
...
$template_file = ABSPATH_THEME . 'tpl.' . $result['template_file'] . '.php';
if(file_exists($template_file)) {
$page = require_once($template_file);
return $page;
}
}
As you see the template file are loaded inside my Page class, and therefore will it not access instances of classes initialized outside my Page class.
I can come up with different solutions:
1) I pass all instances of the different classes to my class Page, when constructing my page. I think this is the right way, but can be very complex if I need 5, 10 or 20 different objects in my design.
2) Find a way to include the template file outside the Page class, but triggered from the get_page() function - have no clue how to do this, and if it is a good solution?
Can you please tell me what is best, and if there are some better ways to do it?
You can just include classes on the top of your php
eg. /CLASSPATH/ClassName.php
And then you can create an entity for that class once and use it everywhere
eg. $entity = new ClassName();
I think your best bet will be to pass them in as arguments, depending on what you need you may want to make them properties.
Edit: This is assuming that by "using instances of other objects" you mean that you need to use objects that have already been instantiated elsewhere.
If by "istances of other classes" you mean other generical objects (you mention PDO and user which are goos examples of this) I would store these in the $_SESSION array (or in $_GLOBAL array, $_SESSION being the best option in most cases).
Then you can access them just by using $_SESSION['PDO']->... and the like
One of the most popular method to handle php application rooting is to implement MVC design patern, or use an MVC Framework. Google 'MVC php' for details, good luck.
Take a look at the functions get_defined_vars and extract. Using these you can export variables from one scope to another.
A silly example could be: A function A transfer locally defined variable to a function B.
function A()
{
$var1 = "1";
$var2 = "2";
// etc
$data = get_defined_vars();
B($data);
}
function B($data)
{
extract($data);
// somescript.php can use $var1, $var2, etc if B is call from A.
require("somescript.php");
}
A();
The best practice is to use a ServiceLocator or an InversionOfControll-Container to retrieve class instances without violation of DI-Principle. For your template file you can create view helper objects to have direct access to other objects.
This is probably a noob question, so please be kind.
I'm trying to implement a cache on an expensive "activity" object. In the constructor I first check the cache to see if this Activity instance already exists. If not, I do all the queries to build up the object, serialize it and save it to cache. The next time I come in, I check the cache and my object is there, so I unserialize it. Now is my problem, how do I put that object into $this, the current object? I can't just say "$this = unserialize($row[0]);" That fails with the error message, "Cannot re-assign $this in ActivityClass.php". What am I missing?
Thanks a ton!
Mike
If you don't want your construction to leave the class, you can create a factory method:
class Activity
{
public static function Create(/* your params */)
{
// construct cache and key, whatever
$obj = unserialize($cache->get($key));
if ($obj) return $obj;
return new Activity(/* params */);
}
// rest of your stuff
}
You'll have to serialize only your object's internal state, i.e. its parameters (aka "member variables"). In fact, in this instance, serialize() isn't really what you want to do; rather, you want to store your ActivityClass's data to your cache, not the serialization of the entire object. This gets tricky, though, because as you add new parameters later you need to remember to store these in your cache as well.
Alternatively, you can implement a singleton or factory pattern for your ActivityClass. Since you say you're pulling the class from the cache in the constructor, I take it that only one instance of this class is meant to exist at any given time? In this case, you should make your class a singleton, by doing the following:
Make the __construct() method private or protected.
Create a public static method (I tend to call this getInstance()) that will check your cache for the object, or instantiate a new one and then cache it.
Now instead of directly instantiating a new ActivityClass object, you instead write $foo = ActivityClass::getInstance();, which gives you either a new object or unserializes and returns your cached one.
As you noticed, you cannot just override the current object as a whole.
Instead, a possibility would be to store the data you're serializing/unserializing into a property of your object.
This way, you wouldn't serialize your whole object, but only one of its properties -- and only that single property would be overriden when unserializing.
Typically, you wouldn't serialize the connection to the database, which could be another property of your object.
Another possibility would be to not have your object deal with its own (de-)serialization.
Instead, you should :
Use an external class to instanciate your object
With that external class being responsible of either :
Loading data from cache and pushing it into your object,
Or calling the right method of your class, to load data from the database -- and, then, save that object to cache.
I am using 'this' keyword for a long time. But when someone asks me to explain it, I am confused that how to explain it. I know that I can use this in a method of class to access any variable and method of the same class.
class MyClass{
function MyMethod1(){
echo "Hello World";
}
function MyMethod2(){
$this->MyMethod1();
}
}
Is it a object of a class that we don't need to initialise and can be used only within the class or anything else. How to explain?
Thanks
A class is a mold for an object: it specifies how the object looks like (variables) and what it can do (functions).
If you instanciate a class: you create an object. If you create the class, you can use "this" to refer to the object itsself. This is why you can't set the "this", because it's related to the object. It's a special, read-only variable.
this references the current object instance of a class.
this is an implicitly parameter passed to the methods of a class: it is scoped to a method and allows access to all of the object's members.
Like their name suggests, instance methods operate on instances of a class. How do they know which one to operate on? That's what the this parameter is for.
When you invoke an instance method, you're really invisibly passing in an extra parameter: the object to invoke it on. For example, when you have this:
class Basket {
public function a() {
$this-> ...;
// ...
}
// ...
}
and you call $some_basket->a(), behind the scenes you're actually calling something like Basket::a($some_basket). Now a() knows which Basket you want to work with. That special parameter is what this refers to: the current object you're dealing with.
short:
$this gives you access to the object variables (and methods) Edit: within the class :) Edit 2: (but not in static methods of the class) :D
Several people have explained it in similar terms, but thought I'd add that when speaking to people unfamiliar with object oriented programming, I explain that the class definition is the blueprint, as for a house, and "this" is the actual house you're working with at that moment. There might be other houses that look exactly the same, but this is the specific object (house).
A class is a template or a 'die' for an object.
Lets use the classic 'bicycle' example. There are many huffy bikes out there. However, we have created one bike, and we can use the 'this' keyword to refer to 'this' bike.
In more a more technical sense, a class is a template for an object that will be instantiated. At run time, after an object has been instantiated, or had an instance of itself created, we can then use the keyword 'this' internally to refer to the instance that runs that method.