I'm learning OOP in PHP and Laravel. So far my idea is that variable and property are more or less the same. Methods are equivalent to functions. But sometimes I see in many articles that they represent variable and property slightly differently. For example in laravel naming conventions, Model property and variable have different terminologies. What are the differences (if any) between variable and property?
Yes, method is a function.
Model property would be a global variable within the class, so you can use it in all the methods. And depending on the access modifier (private, protected, public) the model property can be used from other classes inheriting/instantiating from that class.
While a variable will be something used within a method and has usage only within the body of that method.
A property is an variable that belongs to the object. The are also called "Members". Imho the main Difference is the Scope. A variable is only available within the method but a property in the whole Class and also in the object if you use public as visibility. http://php.net/manual/en/language.oop5.visibility.php
A property (also called a member variable) in PHP OOP is a variable that exists inside of a class, and must be private, protected, or public. For example:
class Bird {
private $color; // This is a property of the Bird class
}
$var = 123; // This is just a normal variable
So the Model Property that the documentation is referring to is just a member variable of the model.
As far as the difference between functions and methods, they are similar except for 1 major difference: methods are functions that exist inside of a class, and must be private, protected, or public. For example:
class Bird {
public function sing() { // This is a method
echo 'tweet-tweet';
}
}
function sayHello() { // This is a function
echo 'hello';
}
Note: If you do not declare a property or method as private, protected, or public, it is assumed that it is public
Related
trait Foo {
private $url = config('api.url');
}
I have a url data set inside of config, however I need to put this value into trait's property. But it's not working. anyone know how to solve this problem?
what I did now is put construct inside of trait
public function __construct(){
$this->url = config('api.url');
}
it's not about traits, it's about php OOP nature itself:
here is the docs:
Class member variables are called "properties". You may also see them
referred to using other terms such as "attributes" or "fields", but
for the purposes of this reference we will use "properties". They are
defined by using one of the keywords public, protected, or private,
followed by a normal variable declaration. This declaration may
include an initialization, but this initialization must be a constant
value--that is, it must be able to be evaluated at compile time and
must not depend on run-time information in order to be evaluated.
from the docs example:
// invalid property declarations:
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
In an effort to keep my code clean, I am attempting to replace a whole bunch of code in my constructor with a function. I believe I am calling the function correctly but i'm not able to assign values to the variables as intended.
public function __construct($docID) {
self::getDocumentInfo($docID);
self::getTranscriptionInfo($docID);
}
private static function getTranscriptionInfo($docID) {
$this->documentTranscription = 5;
}
Im getting an error "PHP Fatal error: Using $this when not in object context in ...". This is simplified for postings purpose, but would it be better just have a very large constructor and skip the functions all together? Or is their a better way to assign values?
A static method is not a part of the class instance. The static keyword means the method can be called within your class but it won't have any of the instance variables.
Remove the static keyword and change this:
self::getDocumentInfo($docID);
self::getTranscriptionInfo($docID);
to this:
$this->getDocumentInfo($docID);
$this->getTranscriptionInfo($docID);
Using $this means it will be calling it within the right instance context.
Some info the static keyword (added emphasis in italics):
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).
Because static methods are callable without an instance of the object created, the pseudo-variable $this is not available inside the method declared as static.
Source
http://php.net/manual/en/language.oop5.static.php
I what to know why can not I able to define a variable in the class without any thing ? (public, private, protect)
why this has syntax error ?
class myclass {
$var = 'anythig';
}
But this is ok:
class myclass {
function test() { // code here }
}
And finally why it is possible to I define a var without anything in function ?
class myclass {
function test() {
$var = 'anything'; // it has not anythig (public, privare, protect)
}
}
When you use any of the programming languages, you should know the rules, otherwise, the behavior of the program will come strange; for example as in your case, while declaring functions in a class, omitting the visibility keywords implies the function will have the public visibility.
About the property visibility:
Class properties must be defined as public, private, or protected. If
declared using var, the property will be defined as public.
And about the method visibility:
Class methods may be defined as public, private, or protected.
Methods declared without any explicit visibility keyword are defined
as public.
And finally about the defining variables, I believe you need to read about the variable scope.
As per request, about the comment above regarding static vs private:
staticness of a class member is intended to deal with the lifetime of the matter (the matter exists regardless of existence of any instance of a class), while privateness is about the visibility of the matter (for example: the existent matter cannot be accessed when it has the private visibility.)
The two are different concepts and are not mutually exclusive (you may use them together.) Mixing these concepts, makes me believe that you're in an urgent need of reading some OOP materials.
I reveal iteresting behavior of php >= 5.2
class A {
protected $a = 'A';
public function __get($f){ return 'field_'.$f; }
}
class B extends A {}
class C extends A {
public function foo() {
$b = new B();
echo $b->a;
}
}
$c = new C();
$c->foo();
I expect it print field_a, but it print A.
Also. If I remove magic from A - I expect fatal error, but it still print A in php>=5.2.
If we overwrite B::$a we get another behavior - fatal error.
Why?
Is it feature or bug?
Fiddles:
- http://3v4l.org/tiOC5 - get foreign field
- http://3v4l.org/uT9PC - get fatal error
This is because of PHP's very funky rules for who can and cannot access class properties.
Read about it here:
http://php.net/manual/en/language.oop5.visibility.php
The key part is this:
The visibility of a property or method can be defined by prefixing the
declaration with the keywords public, protected or private. Class
members declared public can be accessed everywhere. Members declared
protected can be accessed only within the class itself and by
inherited and parent classes. Members declared as private may only be
accessed by the class that defines the member.
Emphasis mine. You are allowed to access the protected variables of any object that inherits from the same class you inherit from, even on another object. This also includes accessing the private properties of other objects of the exact same class.
Whether this is a good idea or a weird feature is up for debate, but it seems to be intended.
I believe if you declare a variable it won't use the __get magic method.
So by declaring protected $a = 'A';, you are excluding a from the __get cycle. It will skip the magic method and go straight for the actual property.
If you look at the documentation for the magic methods __get() and __set() you'll see that they only run in the case of reading/writing to an inaccessible field.
In your example $a is accessible from class C as it's defined as a protected field (inheriting/parent classes can view protected fields/methods). If you change $a to a private field it should have to call the magic method for your example.
Up until today, I thought I had a fairly good grasp of how the static modifier worked. I know that (in laymans terms) a static variable in a function does not 'reset' across calls to that function, and I know that static variables and functions on a class are accessible by calling upon them through the class itself (not an instantiation of the class).
My problem is this: today I found that if I declare a static variable inside of a non-static function on a class, all instantiations of that class share that static variable in separate calls to the member function.
For example:
class A {
public function GetValue() {
static $value = 0;
$value++;
return $value;
}
}
$instance_1 = new A();
$instance_2 = new A();
echo $instance_1->GetValue();
echo $instance_1->GetValue();
echo $instance_2->GetValue();
echo $instance_2->GetValue();
echo $instance_1->GetValue();
echo $instance_1->GetValue();
Notice that the GetValue function is neither declared as static or used in a static way (as in, called on the class itself).
Now, I always assumed that this would output: 121234
Instead, I find that it will output: 123456
Like I say, I would understand this if the static variable $value was inside of a static function. However, with it being inside a non-static function I just assumed that it would only be 'tied' to the function 'within' each individual instantiation.
I guess my question is twofold, then... 1) is this a bug or expected behaviour? 2) do other languages treat these 'static inside non-static' variables the same way, or is this unique to PHP?
This is expected.
This is also the case in C++ (and probably others as well).
You should think of non-static class member functions as if they were just like ordinary functions, but with an implicit $this argument that is automatically provided by the interpreter. (That's exactly how they're implemented in most languages.)
I've copied the following information from this article by Josh Duck: http://joshduck.com/blog/2010/03/19/exploring-phps-static-scoping/
Static variables have been available since PHP 4 and allow you to define a persistent variable that is only accessible from the current function. This allows you to encapsulate state into a function or method and can eliminate the need for classes where a single function will suffice.
When a static variable is defined inside a class method they will always refer to the class on which the method was called. In doing this they act almost like properties referenced through static, though there are subtle differences.
Static variables can’t preserve the calling class scope. This can be potentially problematic if you have an inherited method containing a static variable that is called from both inside and outside its class.
As far as I know, all languages with static variables treat them this way. Think of static variables as global variables that can only be accessed from a certain scope.