How to explain 'this' keyword in a best and simple way? - php

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.

Related

what's meaning of the source code "new CI;" in pyrocms?

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

oop php constructor access modifier, which one to use?

I've just started experimenting with OO PHP, but there's one basic principle I don't really uderstand that well, and don't find too much info on it.
When creating a __construct() method, why would you want it to be public, when it's specifically a constructor for that class?
When would you want to call a constructor outside the class?
To me, it seems using a protected constructor is good practice, right?
I know this is basic OO stuff, but I don't find any info directly on it, specifically for constructors.
The __construct (not "__constructor") method is the one called when you do new MyClass(), i.e. when you instantiate the class. The constructor needs to be public, unless you only want to instantiate the class from within itself. If the latter, you need at least one other public static method you can call in which the class will instantiate itself, otherwise you're unable to create any instance of it.
Whenever you create a new instance of a class, the constructor is called. If the constructor is not public, no other code can create an instance of that class.
Hence, if you want to create instances of the class, make the constructor public.
A constructor is always only part the class it is defined in, I don't understand what you mean by "when it's specifically a constructor for that class".
To clarify:
The only way to invoke the constructor is with new Class(). There is no other way to invoke it. __construct is a magic method and there is no way to explicitly call a magic method.

To store as a class parameter or normal php variable

I am new to OO concepts in PHP. I have a class called MY_ controller which is my base class. All classes extend this class. I am using MVC architecture. I am using caching in my system now. So i load the cache variable in the constructor of my base class. I use normal php variable like $cacheVariable in my function to store the value from cache. I was wondering if it would serve any help if i store it as a class parameter and use like $this->cacheVariable? In each function i get cache value like $this->cache->get('cacheVariable'); will it help if i get value from $this->cacheVariable
If you want to be able to use $cacheVariable anywhere else besides your constructor you'll want to use $this
public function __construct() {
//...
$this->cacheVariable = $this->cache->get('cacheVariable');
//...
}
Also remember, if you want your children classes to inherit this variable from your base class you will need to set it as either public or protected. If it's private children will not inherit it.
When you say "class variable" I assume you are referring to a property (property of an instance=. Note the difference:
if you have a class, say MyClassA, then in your scripts you will instantiate that class using the operator new (depending on your PHP version you can use a different constructor syntax it changed since PHP-5.3.0):
<?php
class MY_controller{
public $cacheVariable;
// constructor
function MY_controller($aValue){
// constructor code which loads cacheVariable, for example with parameter
$this->cacheVariable = $aValue;
}
public function someFunction(){
//... some code, then access the property
$cv = $this->cacheVariable;
}
}
$aController = new MY_controller(42);
?>
As you inherit from MY_controller, every instance of that class, will have access to cacheVariable through $this->cacheVariable.
The important thing I wanted to clarify is that it is an instance property, not a class one. For further reference on OOP in PHP, refer to the properties section in PHP's OOP manual and the inheritance section.
When you instantiate only one instances of your controller (derived from your main controller), its a conceivable solution.
In my opinion the better idea is getting variable directly from cache service everywhere you want in your class and don't keep it as a class property. The reason is simple: let's say value of some key from cache will be changed (or expires) in the other place than your class. If you have this value as class property you need to keeping eye on it every time you access this value but if you retrieving it from cache you just don't care (because the cache cares if value of some key doesn't changed or expired).

PHP and Runtime Subclassing / Object reclassification

Basic setup. I have a classA instance which is a subclass of classX ... On construction (or sometime else), I want it to load another class classB which is also a subclass of classX and replace itself with classB in situ. Sort of like a factory, but one that replaces itself transparently. If need be, I can wrap classB with classA if there is a way to (at runtime) change the subclass of an object.
Currently I am using classA::__call() to emulate MRO magic, but is seems very inelegant. This needs to be done transparently to the caller of classA/B so that to the outside world, it isn't aware that classA has replaced itself with classB after construction (or anywhere else for that matter).
I know PHP can be a bit thin when doing things like this ... I am suspecting we can't, but it would be handy for my situation.
Also, 5.3 but ideally (yuck) 5.2/x
Thanks in advance (wishing I was coding in Python)
Ok, I've taken an interest in this question because I've reached the point where I'd like to discover the exact limits of PHP, including little hacks like this. Hopefully, I'll make sense this late at night and a few beers in me. Because of the ugly hackishness, I'm actually expecting to be downvoted.
Obviously, you can't do $this = $that. You also can't change the global variable you're currently trying to make into an object while it's being constructed, and attempting to do so will be ignored. As Charles said earlier, this can't be reasonably done. Not with clone, not serialize(), nothing within __construct().
So, unreasonably if you want $a to first become an object of class A, then convert mid-creation to class B, try this pseudo method: You'll have to call __construct of class A twice in a row. First time to handle construction of class A. Second time to complete the object converting it to class B. Class A handles the first half of construction, and class B the second half:
class A {
function __construct() {
$args = func_get_args(); // just to tell us the first round of __construct already occured
if (array_key_exists(0, $args) AND $args[0]) {
$GLOBALS['a'] = new B($GLOBALS['a']);
// stop because "reconstruction" has stopped. Nothing else you can do to $a in this scope.
$this->aprop2 = "yay";
// Seriously, stop. Don't bother putting more code at this point, you're wasting your time. Consider $a 'converted and returned' already.
}
// build on an object of class a here
}
}
class B {
function __construct($var) {
// maybe you'd like to do something with old $a? If so, here's $var for you
// continue constructing where A left off.
}
}
$a = new A(); // object of class A
$a->__construct(true); // object of class B
Maybe instead make another method of class A named more importantly sounding, which does the same thing to convert the global $a into object of class B, just so it doesn't look so stupid as my example. In other words, you're probably already doing it as best as PHP allows.
Edit: Really though, the above is nothing more than $a = new A(); $a = new B($a);. For better code readability and maintainability, you may want not to use my example and instead opt to implement a factory or handler class that creates and juggles these objects for you. I found a brief and insightful www.ibm.com article explaining the concept of factories how they are applied in PHP. Maybe conceptually, you want a static class that acts like a cd changer, and this is where Return by Reference - to work with a variable reference to the object in any scope - and Variable Objects (ref: midir's comments on that page) - to dynamically set or work with the object - comes in handy.
This is not currently possible in PHP...
Without doing stupid things.
If every instance of the object is a reference, and those references can be found in $GLOBALS, and the object knows what every one of those instances is called, you could replace each and every reference of the old object with your new object. The outside world won't know the difference.
This is, however, a spectacularly awful idea. Using __call magic is probably the least insane way of accomplishing your goal.
Edit: There's always runkit, which will let you do things like add and remove methods from classes. However, it's a PECL extension and might not even work correctly...

difference between object and static methods

What's the difference between static and object methods? Where and why are they used differently? When do I use which one of those?
With object methods you need to instantiate the class in order to use the method so say Bark is an object method
Dog myDog = new Dog();
myDog.Bark();
But now let's say Bark was a static method. I could just do:
Dog.Bark();
So a static method works on a class, not on an object.
Static methods are useful when you'd like to just make a global utility class. That way you don't need to pass an object around just to use methods on this utility class.
static methods are instantiated only once in the memory space.
Instance methods require an instance of the class to be invoked. The instance reference can be thought of as an invisible first parameter, which can be accessed within the method using the 'this' keyword in C#, C++, and Java. Static methods can be invoked without an instance of the class. They can only access instances of the class if they are passed in as parameters.
As a general rule of thumb, use an instance method when the method performs some operation on a single instance. Use a static method when the method performs an operation on multiple instances, or requires no instances.
PHP manual is very brief about that. But static is explained quite well in the book "PHP 5 Power Programming":
Static properties
Static methods
Singleton pattern (scroll down to the singleton section there)

Categories