When can $this reference variables outside its class in PHP? - php

class A {
public function f(){
$this->ar[0] = 'something';
}
}
For example, how can function f be called such that $this->ar will refer to an array declared outside of class A? Assume that A is not inheriting ar.
Edit:
I tried to simplify the question. The actual code I'm looking at is
the function index in opencart's ControllerStartupStartup class
The function index is using $this to access class instances that aren't defined in that class: $this->db,$this->config, and $this->tax.
They are not declared in the parent class Controller either.
The function is being called with call_user_func_array(array($controller, $this->method), $args); in the Action class.

Maybe you can make "ar" known and provide it in the class as setter, so the instance ar is known and you can address it with $this
class A {
$ar = array();
public function f(){
$this->ar[0] = 'something';
}
}
// INSTANCE with Setter
$ar[0]='whatever';
$class = new A();
$class->ar = &$ar;
$class->f();
echo $ar[0];

Related

Calling Class Method in PHP

When to call class method directly?
<?php
Class::method();
?>
When to call class method after object instatiated?
<?php
$object = new Class();
$object->method();
?>
What are the differences between both of them?
Methods which are defined as static those methods will be called directly.
Like function1 is static so it will be called as
A::function1();
class A
{
public static function function1()
{
$a = "Hi";
return $a;
}
public function function2()
{
$a = "Hi";
return $a;
}
}
Where as second method is not static and it will be called on the object of class A like below
$object = new A();
$object->function2();
:: scope resolution operator that is used for direct call static class methods without object
Class::method();
you can use class variables $this->... in this method.
$object = new Class(); new is create object of class and you can also use class variables from object
in simple way object is instance of class.
if you are making any class function static then you can access by using scope resolution operator like in 1st case.In case of static function $this is not available inside function.
<?php
class Product
{
public static function method() //static function
{
echo "static function" ;
}
}
Product::method(); // we can make direct call
?>
while in 2nd case object is created and we are accessing class methods through objects.
$object = new Class();
$object->method();

Use one class variables in another class

How do I can access base class variables in another classes wich are loaded into base class?
Base class example
class base {
public $get;
public function __get( $name ) {
require_once $name . '.php';
$this->name = new $name( $this );
return $this->name;
}
public function __construct( $varfromphplib ) {
$this->varfromphplib = $varfromphplib;
$this->get = explode( "/", $_SERVER['REQUEST_URI'] );
}
}
$class = new base( $varfromphplib );
another class example (loaded into base class with __get)
class another {
public function showGet() {
//there I wanna return base class $this->get;
}
public function getLibClass(){
//there I wanna return $varfromphplib variable with baseclass prefix or not if can
}
}
//usage in base class
$this->another->showGet( );
I don't know how to be able to acces base class variables like $get in "another" class
Hope someone will be able to help me with this.
If one class is inherited from the other (A extends B) you can call variables from the parent class by using $this->variable. Note that this only works if the inheriting class doesn't have an own constructor and doesn't have a variable by the same name.
If any of that keeps you from using $this, you can always call the parent classes variables just like you would call any public variables from unrelated classes.
i.e.: A has protected variable $a and B extends A but has an own variable named $b.
$objA = new A();
echo "A->a = ".$objA->a;

PHP new static($variable)

$model = new static($variable);
All these are within a method inside a class, I am trying to technically understand what this piece of code does. I ran around in the Google world. But can't find anything that leads me to an answer. Is this just another way of saying.
$model = new static $variable;
Also what about this
$model = new static;
Does this mean I'm initializing a variable and settings it's value to null but I am just persisting the variable not to lose the value after running the method?
static in this case means the current object scope. It is used in late static binding.
Normally this is going to be the same as using self. The place it differs is when you have a object heirarchy where the reference to the scope is defined on a parent but is being called on the child. self in that case would reference the parents scope whereas static would reference the child's
class A{
function selfFactory(){
return new self();
}
function staticFactory(){
return new static();
}
}
class B extends A{
}
$b = new B();
$a1 = $b->selfFactory(); // a1 is an instance of A
$a2 = $b->staticFactory(); // a2 is an instance of B
It's easiest to think about self as being the defining scope and static being the current object scope.
self is simply a "shortcut name" for the class it occurs in. static is its newer late static binding cousin, which always refers to the current class. I.e. when extending a class, static can also refer to the child class if called from the child context.
new static just means make new instance of the current class and is simply the more dynamic cousin of new self.
And yeah, static == more dynamic is weird.
You have to put it in the context of a class where static is a reference to the class it is called in. We can optionally pass $variable as a parameter to the __construct function of the instance you are creating.
Like so:
class myClass {
private $variable1;
public function __construct($variable2) {
$this->variable1 = $variable2;
}
public static function instantiator() {
$variable3 = 'some parameter';
$model = new static($variable3); // <-this where it happens.
return $model;
}
}
Here static refers to myClass and we pass the variable 'some parameter' as a parameter to the __construct function.
You can use new static() to instantiate a group of class objects from within the class, and have it work with extensions to the class as well.
class myClass {
$some_value = 'foo';
public function __construct($id) {
if($this->validId($id)) {
$this->load($id);
}
}
protected function validId($id) {
// check if id is valid.
return true; // or false, depending
}
protected function load($id) {
// do a db query and populate the object's properties
}
public static function getBy($property, $value) {
// 1st check to see if $property is a valid property
// if yes, then query the db for all objects that match
$matching_objects = array();
foreach($matching as $id) {
$matching_objects[] = new static($id); // calls the constructor from the class it is called from, which is useful for inheritance.
}
return $matching_objects;
}
}
myChildClass extends myClass {
$some_value = 'bar'; //
}
$child_collection = myChildClass::getBy('color','red'); // gets all red ones
$child_object = $child_collection[0];
print_r($child_object); // you'll see it's an object of myChildClass
The keyword new is used to make an object of already defined class
$model = new static($variable);
so here there is an object of model created which is an instance of class static

Instantiating classes and accessing methods from different classes

I'm trying to use a Class_B function in one of Class_A's functions. But a lot of Class_B's functions include $this which causes problems. These are both classes (each class is of course in its own file):
class Class_A
{
function hello()
{
require('class_b.php');
echo 'Hello ' . Class_B::person();
}
function bye()
{
require('class_b.php');
echo 'Bye ' . Class_B::person();
}
}
class Class_B
{
function person()
{
// various operations and variables
echo $this->get_user($id);
}
}
When I run the Class_A file I get Call to undefined method Class_A::person() in (...) because I think the $this value is changed when I instantiate the Class_A class. It overrules the Class_B value. How can I stop this?
Also, another question: how can I access Class_B from every function in Class_A? I don't want to redeclare the class. Do I need to do this:
class Class_A
{
function function1()
{
require('class_b.php');
$class_b = new Class_B();
// code
}
function function2()
{
require('class_b.php');
$class_b = new Class_B();
// code
}
}
Or do I need to use a constructor or something?
By Class_B::person() you are calling the method statically. So you should declare the person() method as static and can't use $this because you don't have an instance of Class_B.
If you need an instance of Class_B, just create it and store in the class_B on construction.
class Class_A {
private $b;
function __construct()
{
$this->b = new Class_B();
}
function stuff()
{
$this->b->person();
}
Don't put require inside a method. Code in an included file inherits the scope of the place where you include it, and in your example, bad things happen. Also, for class definition scripts, consider require_once instead of require, to avoid multiple definitions.
As a rule of thumb, put all includes and requires at the top of your script. Better yet, set up a class autoloader, and register it in an auto_prepend script. That way, you won't have to manually include anything at all (at least not for class definitions).
What you might want is dependency injection, whereby you pass an object of Class_B into Class_A's constructor and hold it as a property in Class_A. It then becomes available in Class_A as $this->classB or similar.
// Include Class_B code outside the class.
require_once('class_b.php');
class Class_A {
// Property to hold Class_B
public $b;
// Constructor
public function __construct($b) {
$this->b = $b;
}
public function function1(){
// code
$this->b;
}
public function function2(){
// code
$this->b;
}
}
// Now call your objects:
// The Class_B which will be injected into A
$b = new Class_B();
// Your Class_A, which holds an instance of Class_B as a property
$a = new A($b);

PHP Classes: when to use :: vs. ->?

I understand that there are two ways to access a PHP class - "::" and "->". Sometime one seems to work for me, while the other doesn't, and I don't understand why.
What are the benefits of each, and what is the right situation to use either?
Simply put, :: is for class-level properties, and -> is for object-level properties.
If the property belongs to the class, use ::
If the property belongs to an instance of the class, use ->
class Tester
{
public $foo;
const BLAH;
public static function bar(){}
}
$t = new Tester;
$t->foo;
Tester::bar();
Tester::BLAH;
The "::" symbol is for accessing methods / properties of an object that have been declared with the static keyword, "->" is for accessing the methods / properties of an object that represent instance methods / properties.
Php can be confusing in this regard you should read this.
What's also confusing is that you can call non static functions with the :: symbol. This is very strange when you come from Java. And it certainly surprised me when I first saw it.
For example:
class Car
{
public $name = "Herbie <br/>";
public function drive()
{
echo "driving <br/>";
}
public static function gas()
{
echo "pedal to the metal<br/>";
}
}
Car::drive(); //will work
Car::gas(); //will work
$car = new Car();
$car->drive(); // will work
$car->gas(); //will work
echo $car->name; // will work
echo Car::$name; // wont work error
As you can see static is very loose in php. And you can call any function with both the -> and the :: symbols. But there is a difference when you call with :: there is no $this reference to an instance. See example #1 in the manual.
When you declare a class, it is by default 'static'. You can access any method in that class using the :: operator, and in any scope. This means if I create a lib class, I can access it wherever I want and it doesn't need to be globaled:
class lib
{
static function foo()
{
echo "hi";
}
}
lib::foo(); // prints hi
Now, when you create an instance of this class by using the new keyword, you use -> to access methods and values, because you are referring to that specific instance of the class. You can think of -> as inside of. (Note, you must remove the static keyword) IE:
class lib
{
function foo()
{
echo "hi";
}
}
$class = new lib;
$class->foo(); // I am accessing the foo() method INSIDE of the $class instance of lib.
It should also be noted that every static function can also be called using an instance of the class but not the other way around.
So this works:
class Foo
{
public static function bar(){}
}
$f = new Foo();
$f->bar(); //works
Foo::bar(); //works
And this doesn't:
class Foo
{
protected $test="fddf";
public function bar(){ echo $this->test; }
}
$f = new Foo();
$f->bar(); //works
Foo::bar(); //fails because $this->test can't be accessed from a static call
Of course you should restrict yourself to calling static methods in a static way, because instantiating an instance not only costs memory but also doesn't make much sense.
This explanation was mainly to illustrate why it worked for you some of the times.
:: is used to access a class static property. And -> is used to access a class instance ( Object's ) property.
Consider this Product class that has two functions for retrieving product details. One function getProductDetails belongs to the instance of a class, while the other getProductDetailsStatic belongs to the class only.
class Product {
protected $product_id;
public function __construct($product_id) {
$this->product_id = $product_id;
}
public function getProductDetails() {
$sql = "select * from products where product_id= $this->product_id ";
return Database::execute($sql);
}
public static function getProductDetailsStatic($product_id) {
$sql = "select * from products where product_id= $product_id ";
return Database::execute($sql);
}
}
Let's Get Products:
$product = new Product('129033'); // passing product id to constructor
var_dump( $product->getProductDetails() ); // would get me product details
var_dump( Product::getProductDetailsStatic('129033') ); // would also get me product details
When to you use Static properties?
Consider this class that may not require a instantiation:
class Helper {
static function bin2hex($string = '') {
}
static function encryptData($data = '') {
}
static function string2Url($string = '') {
}
static function generateRandomString() {
}
}
Sourcing WikiPedia - Class
In object-oriented programming, a
class is a programming language
construct that is used as a blueprint
to create objects. This blueprint
describes the state and behavior that
the created objects all share. An
object created by a class is an
instance of the class, and the class
that created that instance can be
considered as the type of that object,
e.g. a type of an object created by a
"Fruit" class would be "Fruit".
The :: operator accesses class methods and properties which are defined in php using the static keyword. Class const are also accessed using ::
The -> operator accesses methods and properties of an Instance of the class.
If the function operates on an instance, you'll be using ->. If it operates on the class itself, you'll be using ::
Another use of :: would be when you want to call your parent functions. If one class inherits another - it can override methods from the parent class, then call them using parent::function()

Categories