New to php. I am writing a class and was wondering why some variable $variable does not need a $ when calling $this->variable?
In Object Oriented Programming when you declare variables like so
public $variable;
these are no more variables but are the properties of the object of the class.
So when we call these properties we reference these through $this->property Which means that we are calling the property of the present object. $this refers to the instance of the present class. Whenever you would call properties and methods within class you have to use $this->property-or-method.
It is not the variable. It means object oriented.
It's a reference to the current object, it's most commonly used in object oriented code.
Reference: http://www.php.net/manual/en/language.oop5.basic.php
Primer:http://www.phpro.org/tutorials/Object-Oriented-Programming-with-PHP.html
Example:
<?php
class Person {
public $name;
function __construct( $name ) {
$this->name = $name;
}
};
$jack = new Person('Jack');
echo $jack->name;
This stores the 'Jack' string as a property of the object created.
Because that variable is inside a larger variable called an Object and the object knows how to access it's inner variables / functions. Like a smart-variable.
Objects can be used to group data or similar functions (called method's when they are inside of an object)
For data/values, you could also use an array. It's common to see data stored in objects as well.
But you wouldn't store functions in an array. In PHP that's a no-go, but in JavaScript that's all good.
Back to objects, functions stored in objects are called methods. Objects can contain methods or properties.
Object Method / Function Example from: http://php.net/manual/en/language.types.object.php
<?php
class foo
{
function do_foo()
{
echo "Doing foo.";
}
}
$bar = new foo;
$bar->do_foo();
// also valid $bar::do_foo();
?>
Object Property / Variable Example From: http://php.net/manual/en/language.oop5.properties.php
<?php
class SimpleClass
{
// valid as of PHP 5.6.0:
public $var1 = 'hello ' . 'world';
// valid as of PHP 5.3.0:
public $var2 = <<<EOD
hello world
EOD;
// valid as of PHP 5.6.0:
public $var3 = 1+2;
// invalid property declarations:
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
// valid property declarations:
public $var6 = myConstant;
public $var7 = array(true, false);
// valid as of PHP 5.3.0:
public $var8 = <<<'EOD'
hello world
EOD;
}
?>
Related
I have a class
Class MyClass{
private $prop1;
private $prop2; // this contains an array object
public function __construct(){ }
public function set_prop2($prop2)
{
$this->prop2= $prop2; // value coming from other class that returns array object
}
public function func1()
{
global $prop1;
global $prop2;
$var1 = // some value;
$var2 = $prop1;
$var3 = // some value;
$obj = new SomeClass($prop2);
$json = $obj->setVar2($var2)
->someMethod($var1, $otherMethod)
->method();
}
}
using global properties inside method, the class above works for me by calling
obj1 = new MyClass();
obj1->func1(); // I want to call it like this (without parameters)
I know declaring global inside the method is not a good thing but its the only way I can make the method works!
any ideas how I can better the syntax so I can call the method without parameters like obj1->func1(); is greatly appreciated.
NOTE: tried to declare as
$this->prop1;
$this->prop2;
but it gives me a Catchable fatal error: Argument 1 passed to... because $prop2 was not passed properly if using $this->prop2;
Class MyClass{
public $prop1;
public $prop2; // this contains an array object
public function __construct(){ }
public function set_prop2($prop2)
{
$this->prop2= $prop2; // value coming from other class that returns array object
}
public function func1()
{
$var1 = // some value;
$var2 = $this->prop1;
$var3 = // some value;
$obj = new SomeClass($this->prop2);
$json = $obj->setVar2($var2)
->someMethod($var1, $otherMethod)
->method();
}
}
You are confusing 3 different things here:
Global variables, which exist outside any function, class, or object, have to be "imported" into the current scope with the global keyword. They are generally considered bad practice as they lead to code which "magically" transports data from one place to another, making reuse, testing, and debugging more difficult.
Object properties are declared in a class definition, and belong to an instance of that class (or to the class itself, in the case of static variables). They are accessed with the syntax $object->property. The private keyword means the variable can only be seen inside the class, by using the special variable $this, meaning "this object I am inside", e.g. echo $this->prop1;
Function arguments are passed in when you call a function. Inside the function, they are local variables with the names given in the function definition, so do not need to be imported or prefixed in any way. Object methods are basically just functions "attached to" a particular object, and work in the same way.
In your example, you have a comment against an object property here...
private $prop2; // this contains an array object
...but you then say that using that variable (with $this->prop2) gave an error (which you haven't actually shown us properly yet) suggesting that it was not an array. (As mentioned in the comments, "array object" is an odd choice of words. I'm going to assume you just meant "array" for now.)
You then "solve" this by instead using a global variable...
global $prop2;
$obj = new SomeClass($prop2);
...which is a completely different variable.
You also show a definition of a method for setting your private property...
public function set_prop2($prop2)
...but you never show us where you're calling it.
You've annotated it with a comment suggesting where you think it's being called...
// value coming from other class that returns array object
...but the entire question hinges on where that function argument comes from.
One of the things that makes your code hard to read is that the object property, the global variable, and the function argument all have the same name. This doesn't make them the same variable.
What you could try is separating out the different variables, and looking at each in turn:
class MyClass {
private $private_property;
public function set_prop2($new_value_for_prop2) {
var_dump($new_value_for_prop2); // what's the value passed in?
$this->private_property = $new_value_for_prop2;
}
public function func1() {
var_dump($this->private_property); // what value is it now?
}
}
$function_return = some_function();
var_dump($function_return); // is it an array?
$obj = new MyClass;
$obj->set_prop2($function_return); // should show you the value being set
$obj->func1(); // should show the same value again
You can use session functions but I'm not sure that is a good idea for the security... Depend the critical of the parametres...
<?php
Class MyClass{
private $prop1;
private $prop2; // this contains an array object
public function __construct(){ }
public function set_prop2($prop2)
{
$this->prop2= $prop2; // value coming from other class that returns array object
}
private function func1()
{
$prop1 = $_SESSION['prop1'];
$prop2 = $_SESSION['prop2'];
$var1 = // some value;
$var2 = $prop1;
$var3 = // some value;
$obj = new SomeClass($prop2);
$json = $obj->setVar2($var2)
->someMethod($var1, $otherMethod)
->method();
}
}
?>
And for calling :
<?php
session_start();
$_SESSION['prop1'] = $prop1;
$_SESSION['prop2'] = $prop2;
obj1 = new MyClass();
obj1->func1();
?>
Is there a way to set or modify the variable $this in PHP? In my case, I need to call an anonymous function where $this refers to a class that is not necessarily the class that made the call.
Pseudo-example:
function test() {
echo $this->name;
}
$user = new stdclass;
$user->name = "John Doe";
call_user_func(array($user, "test"));
Note: this will generate an error, because, in fact, the function expects an array containing an object and a method that exists in this object, and not any method of global scope.
Why not try setting the function definition to accept an object as a parameter? For example:
function test($object) {
if (isset($object->name)) // Make sure that the name property you want to reference exists for the class definition of the object you're passing in.
echo $object->name;
}
}
$user = new stdclass;
$user->name = "John Doe";
test($user); // Simply pass the object into the function.
The variable $this, when used in a class definition, refers to the object instance of the class. Outside of a class definition (or in a static method definition), variable $this has no special meaning. When you attempt to use $this outside of the OOP pattern, it loses meaning and call_user_func(), which relies on the OOP pattern, will not work in the way that you've attempted.
If you're using functions in a non-OOP way (like global functions), the function is not tied to any class/object and should be written in a non-OOP way (passing in data or otherwise using globals).
You can use the bind method on a closure object to change the meaning of this in a particular context. Note this functionality became available in PHP 5.4.
Official Description
Duplicates a closure with a specific bound object and class scope
class TestClass {
protected $var1 = "World";
}
$a = new TestClass();
$func = function($a){ echo $a." ".$this->var1; };
$boundFunction = Closure::bind($func, $a, 'TestClass');
$boundFunction("Hello");
// outputs Hello World
An alternative to this syntax it to use the bindTo method of an instance of a closure (anonymous function)
class TestClass {
protected $var1 = "World";
}
$a = new TestClass();
$func = function($a){ echo $a." ".$this->var1; };
$boundFunction = $func->bindTo($a, $a);
$boundFunction("Hello");
// outputs Hello World
In your example the relevant code would be
$test = function() {
echo $this->name;
};
$user = new stdclass;
$user->name = "John Doe";
$bound = $test->bindTo($user, $user);
call_user_func($bound);
I'm new to PHP and practicing using static variables. I decided to grab an example that I learnt from C++ and re-write it for PHP (example from the bottom of this article).
There's a class with two private variables (one static), a constructor and a get-method. The constructor assigns the static variable's value to the second private variable, and then increments.
<?php
class Something
{
private static $s_nIDGenerator = 1;
private $m_nID;
public function Something() {
$m_nID = self::$s_nIDGenerator++;
echo "m_nID: " . $m_nID . "</br>"; //for testing, can comment this out
}
public function GetID() {
return $m_nID;
}
}
// extra question:
// static variable can be assigned a value outside the class in C++, why not in PHP?
// Something::$s_nIDGenerator = 1;
$cFirst = new Something();
$cSecond = new Something();
$cThird = new Something();
echo $cFirst->GetID() . "</br>";
echo $cSecond->GetID() . "</br>";
echo $cThird->GetID() . "</br>";
?>
Using the echo test in line 9 to see if m_nID is getting a value I see:
m_nID: 1
m_nID: 2
m_nID: 3
But these values are not being returned by the "->GetID()" calls. Any ideas why?
Edit: both replies so far have solved this, I wish I could "check" them both, so thank you! I'll leave the original code in the question as-is for any future people who have a similar problem
Your background in C++ led up to this issue, which is an easy mistake to make. In PHP, all instance (or object) variables are referenced using $this->, and static (or class) variables with self::. Based on your code:
public function GetID() {
return $m_nID;
}
Access to the private variable $m_nID should be scoped like this:
public function GetID() {
return $this->m_nID;
}
And inside your constructor:
$m_nID = self::$s_nIDGenerator++;
It should have been:
$this->m_nID = self::$s_nIDGenerator++;
Q & A
Why is there no need to put $ before m_nID when using $this->
The above two ways of referencing instance and class variables come with a very different kind of syntax:
$this is the instance reference variable and any properties are accessed using the -> operator; the $ is not repeated for the property names themselves, although they're present in the declaration (e.g. private $myprop).
self:: is synonymous to Something:: (the class name itself); it doesn't reference an instance variable and therefore has no $ in front of it. To differentiate static variables from class constants (self::MYCONST) and class methods (self::myMethod()) it's prefixed with a $.
Extra
That said, $this->$myvar is accepted too and works like this:
private $foo = 'hello world';
function test()
{
$myvar = 'foo';
echo $this->$foo; // echoes 'hello world'
}
class Something{
private static $s_nIDGenerator = 1;
private $m_nID;
public function Something() {
$this->m_nID = self::$s_nIDGenerator++;
}
public function GetID() {
return $this->m_nID;
}
}
It is interesting to note the difference between using self::$s_nIDGenerator on a static variable vs using $this->s_nIDGenerator on a static variable, whereas $this-> will not store anything.
I'm trying to figure out the difference between $_data vs $this->_data
class ProductModel
{
var $_data = null; <--- defined here
function test()
{
$this->_data = <--- but it's accessed using $this
}
}
I know in PHP var is used to define class properties but Why is it accessed using $this. Shouldn't it be like $this->$_data ? What's OOP concept is being used here ? Is it a PHP specific?
PHP along with several other popular programming languages such as Java (it's important to note that PHP's Object Oriented choices were at least partially inspired by Java) refer to the current object instance in context as this. You can think of this, (or $this in PHP) as the "current object instance."
Inside of class methods, $this refers to the current object instance.
A very small example using what you have above:
$_data = 'some other thing';
public function test() {
$_data = 'something';
echo $_data;
echo $this->_data;
}
The above will output somethingsome other thing. Class members are stored along with the object instance, but local variables are only defined within the current scope.
No, it shouldn't. Since PHP can evaluate member names dynamically, the line
$this->$_data
refers to a class member, which name is specified in local $data variable. Consider this:
class ProductModel
{
var $_data = null; <--- defined here
function test()
{
$member = '_data';
$this->$member = <--- here you access $this->_data, not $this->member
}
}
var $_data defines a class variable, $this->_data accesses it.
If you do $this->$foo it means something else, just like $$foo : if you set $foo = 'bar', those two expressions are respectively evaluated as $this->bar and $bar
I have built a class in PHP and I must declare a class variable as an object. Everytime I want to declare an empty object I use:
$var=new stdClass;
But if I use it to declare a class variable as
class foo
{
var $bar=new stdClass;
}
a parse error occurs. Is there a way to do this or must I declare the class variable as an object in the constructor function?
PS: I'm using PHP 4.
You can only declare static values this way for class members, i.e. ints, strings, bools, arrays and so on. You can't do anything that involves processing of any kind, like calling functions or creating objects.
You'll have to do it in the constructor.
Relevant manual section:
In PHP 4, only constant initializers for var variables are allowed. To initialize variables with non-constant values, you need an initialization function which is called automatically when an object is being constructed from the class. Such a function is called a constructor (see below).
Classes and Objects (PHP 4). A good read everytime!
You should not create your object here.
You should better write setter and getter
<?php
class foo
{
var $bar = null;
function foo($object = null)
{
$this->setBar($object);
}
function setBar($object = null)
{
if (null === $object)
{
$this->bar = new stdClass();
return $this;
}
$this->bar = $object;
return $this;
}
}
By the way, you should use PHP5 to work with OOP, which is more flexible...