Every example I've seen for defining a variable in a class, does so outside of any methods, for example:
class Testclass
{
public $testvar = "default value";
function dosomething()
{
echo $this->testvar;
}
}
$Testclass = new Testclass();
$Testclass->testvar = "another value";
$Testclass->dosomething();
How would you go about defining a variable inside a method, and making that definition available to any other method inside that class?
Note that I would only want to define the variable in one function, not have a different definition for each function.
I think you should read up on good object oriented practices. I mean, why do you want to make a variable available "inside a method"?
Variable's created within methods are local to that specific method and as such, scope is restricted to it.
You should instead use a instance member/variable which is available object wide if your trying to access a variable between methods. Or possibly you could pass the variable by ref between methods. Of course if its a value which never changes then it should be static variable on the class (class member).
I suggest having a read of the the OO tutorial on tutsplus. Tutsplus are generally great quality. http://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762
Alternatively, you could do the OO python course (intro to computer science) on Udacity - its also very high quality. Don't worry that its Python, specific language and syntax is irrelevant when trying to understand core OO concepts. https://www.udacity.com/course/cs101
Also, this is a common topic so have a search around, ie Passing Variables between methods?
I hope that helps
Edit: to address your comment. something like this:
class Testclass
{
private $csvResult = []; // instance member array to store csv results
function dosomething()
{
$this->$csvResult = fgetcsv($blah);
}
function processResult()
{
foreach ($this->$csvResult as $item) {
var_dump($item)
}
}
}
But again, as Adrian Cid Almaguer mentioned, you really are best to build a solid foundation of OO for yourself instead of just using this example without truly understanding it.
The real name of the variables class is "properties". You may also see them referred to using other terms such as "attributes" or "fields". In OOP (Object Oriented Programming) You can't define a property inside a method (the real name of a class function is method, not function), because this is a attribute of a class, not an attribute
of a method.
The properties define the attributes of a class, and the methods defines the behavior of a class. For example if you have a class named Person, the person have Name and Age, they are your properties, they are the attributes that describe your class, they can't be inside a method that describe a behavior of your class because the properties of your class must be accessed from any method that need it to show his behavior.
You can read some examples in:
http://www.killerphp.com/tutorials/object-oriented-php/
Related
PHP allows use of static member functions and variables, since 5.3 including late static bindings:
class StaticClass {
public static $staticVar;
...
}
$o = new StaticClass();
Currently, there are various options to access those static members:
$o->staticVar; // as instance variable/ function
$o::staticVar; // as class variable/ function
Other options exist for accessing members from inside the class:
self::$staticVar; // explicitly showing static usage of variable/ function
static::$staticVar; // allowing late static binding
Restructuring some existing classes that make some use of static members I've asked myself if there are best practices for working with static members in PHP?
Well, obviously, they all do different things.
$o->staticVar
This is invalid, since you cannot/should not access static properties with the instance property syntax.
StaticClass::$staticVar
This very plainly accesses a specific static variable on a very specific class.
$o::$staticVar
This accesses the static variable on the class that $o is an instance of. It's mostly used as a shorthand for the previous method and is equivalent in all respects. Obviously though, which class is used exactly depends on what class $o is an instance of.
self::$staticVar
This can be used only inside a class, and will always refer to the class that it's written in. It's a good idea to use this inside a class instead of StaticClass::$staticVar if the class refers to itself, since you don't need to worry about anything if you change the class name later. E.g.:
class Foo {
protected static $bar = 42;
public function baz() {
self::$bar; // good
Foo::$bar // the same, but should be avoided because it repeats the class name
}
}
static::$staticVar
This can also only be used inside a class and is basically the same as self above, but resolves with late static binding and may hence refer to a child class.
What the "best practice" is is debatable. I'd say you should always be as specific as necessary, but no more. $o::$staticVar and static::$staticVar both allow the class to vary through child classes, while self::$staticVar and StaticClass::$staticVar do not. Following the open/closed principle, it's a good idea to use the former, more variable method to allow for extensions.
Properties, both static and non-static, should also not be public to not break encapsulation.
Also see How Not To Kill Your Testability Using Statics.
First of all, don't use $this->staticVar. I am unsure when this changed (I believe PHP 5.4), but in recent versions it is no longer possible to retrieve static variables this way.
As for using late static binding, don't use it if you don't need it. The reason to use it would be if you plan to use inheritance and expect to change the value of the static variable in a derived class.
I've been wondering if a class property is instantiated and used only in one class method should it be a class property at all or should it just be a local variable accessible to that class method only?
For example, should I keep a variable only used in one method as a local variable like this:
class myClass
{
public function myMethod()
{
$_myVariableUsedOnlyOnce = "Hello World";
echo $_myVariableUsedOnlyOnce;
}
}
Or should I make the variable a private class property like this:
class myClass
{
private $_myVariableUsedOnlyOnce;
public function myMethod()
{
$this->_myVariableUsedOnlyOnce = "Hello World";
echo $this->_myVariableUsedOnlyOnce;
}
}
Which approach "smells"? What are the benefits to making all method variables class properties other than when I need to print_r() the entire object for debugging purposes?
Thanks
If you need it to have persistence across function calls, a class property would be best so that it moves around as the object does. You also might want to use it for other reasons in future in other functions. However, it does add overhead.
Generally, the class should have some real-world analogue, so if your variable corresponds to something that makes sense e.g. a person class has a $height, then it belongs as a class property. Otherwise, if it's just a part of the internal calculations of a method, then it doesn't really belong attached to the class e.g. a person does not have a $shoelaceIterator or whatever.
I'd argue that a confusing object design would be more of a smell than a potentially small memory overhead (although this depends on how big the variable is).
These local variables are not properties of your object.
They are not defining your object, then they should not be declared as private member.
First I would ask if you really need the variable/property at all if you are only using it once. As for which one "smells", a property is stored in memory for the entire life of the object whereas the variable is only in memory until the method finishes executing.
If you don't need a variable outside the method, it should not be any property of the class. Moreover, accessing local variables is faster.
In a pure design approach I would suggest you to make your choice according to what the attribute/property is supposed to model.
In pure performance terms, having one static attribute is better because memory space won't be allocate with each instance of the class.
Can I define a class constant inside the class constructor function ?
(based on certain conditions)
That goes against the idea of class constants - they should not be dependent on a specific instance. You should use a variable instead.
However, if you insist on doing this, are very adventurous and can install PHP extensions, you can have a look at the runkit extension that allows to modify classes and their constants at runtime. See this doc: http://www.php.net/manual/en/function.runkit-constant-add.php
I don't think you can.
It wouldn't make sense, either - a class constant can be used in a static context, where there is no constructor in the first place.
You'll have to use a variable instead - that's what they're there for.
Try look here:
http://php.net/manual/en/language.oop5.constants.php
http://php.net/manual/en/language.oop5.static.php
Hope this helps.
As far as standard instance constructors go, there is no way to do this, and as others have pointed out, it wouldn't make sense. These constructors are called per created object instance, at the point they are created. There is no guarantee this constructor would get called before some code tried to access the constant. It also doesn't make sense in that the code would get called over and over again each time a new instance was constructed, whereas a const should only get set once.
It would be nice if PHP either offered some kind of static constructor that let you set the value one time for uninitialized constants, or allowed more types of expressions when defining constants. But these are not currently features of PHP. In 2015 an RFC was made that proposed adding static class constructors, but it is, at the time of me writing this answer, still in the draft status, and has not been modified since 2017.
I think the best alternative for now is to not use constants in this kind of scenario, and instead use static methods that return the value you want. This is very simple in that it only uses the PHP language features as is (not requiring any special extensions), these static methods can be called in the standard way, and you don't need to hack the autoloading process to call some kind of initializer function that sets static variables. The method might need to rely on private static variables in order to make sure the same instance is returned every time, if an object instance is being returned. You would need to write the implementation of this method to be constant like in the sense that it will always return the same thing, but takes advantage of being able to do things you can't do with a constant, like return on object instance or rely on complex expressions or function calls. Here is an example:
final class User
{
/** #var DefinitelyPositiveInt|null */ private static $usernameMaxLength;
public static function getUsernameMaxLengthConst(): DefinitelyPositiveInt
{
if ($usernameMaxLength === null) {
$usernameMaxLength = new DefinitelyPositiveInt(40);
}
return $usernameMaxLength;
}
}
$usernameInput.maxLength = User::getUsernameMaxLengthConst();
This is still not a perfect solution because it relies on the programmer to write these in a constant like way when that is desired (always returning the same value). Also, I don't like that the best place to document the fact that it is a const is in the method name, thus making it even longer to call. I also don't like that you now have to call it as a method instead of just accessing a property, which would be syntactically nicer.
This example is essentially an implementation of a singleton, but sometimes the purpose of a singleton is to be a constant rather than just a singleton. What I mean is, you might want the instance to always exist, and it might be an immutable type (none of the properties are public or mutable, only having methods that return new objects/values).
I am sorry to break it to you but it is not possible in vanilla PHP.
I am not very sure about frameworks or extensions but I am sure that it is not possible in vanilla PHP.
I recommend you to use variables instead.
You still can't, but maybe some of these (progressively weirder) ideas (just ideas, not true solutions) will work for you:
(1) You could use a private property, with a public getter method. The property cannot be modified outside the class, such as constants, but unfortunately it is accessed as a method, not as a constant, so the syntax is not the same.
class aClass{
private $const;
function __construct($const){
$this->const=$const;
}
function const(){
return $this->const;
}
}
$var1=new aClass(1);
echo $var1->const(); //Prints 1
(2) If you really want this value to be accessed as constant from outside, you can use define () inside the constructor. Unfortunately it doesn't get tied to the class or object name (as it do when you use const, using for example myClass::myConst). Furthermore, it only works if you create a single instance of the class. The second object you create is going to throw an error for redefining the constant, because is untied.
class otherClass{
function __construct($const){
define('_CONST',$const);
}
function const(){
return _CONST;
}
}
$var2=new otherClass('2');
echo $var2->const(); //Prints 2
echo _CONST; //Prints 2
#$var3=new aClass('3'); //Notice: Constant _CONST already defined
echo _CONST; //Still prints 2!
(3) Perhaps that last problem can be solved by giving variable names to the constants, related to the object to which they belong. This may be a bit weird... but maybe it works for someone.
class onemoreClass{
private $name;
function __construct($const,$name){
$this->name=$name;
$constname=$this->name."_CONST";
define($constname,$const);
}
function const(){
return constant($this->name.'_CONST');
}
}
$name='var4';
$$name=new onemoreClass(4,$name);
echo $var4->const(); //Prints 4
echo var4_CONST; //Prints 4
$name='var5';
$$name=new onemoreClass(5,$name);
echo $var5->const(); //Prints 5
echo var5_CONST; //Prints 5
Im new to PHP Object Oriented Programming but I know to code in procedural way.
If this is my PHP Class
<?php
class person {
var $name;
function __construct($persons_name) {
$this->name = $persons_name;
}
function get_name() {
return $this->name;
}
}
?>
and if I access it in my PHP page
$jane = new person("Jane Doe");
echo "Her name is : ".$jane->get_name();
Question:
Is it really necessary to put the var $name; in my PHP class since
I can correctly get an output of Her name is : Jane Doe even without the var $name; in my PHP class?
Not technically, no, PHP is very forgiving to things like this. But it is good practice, if only for documentation purposes.
Probably more importantly, declaring the property explicitly lets you set its visibility. In your example $name is a public property (public is the default visibility in PHP). If you don't need it to be public (it's often safer not to, due to getters/setters allowing better control over what values can be assigned) then you should declare if protected or private.
Semantically, you should, as $name is indeed an attribute of your class. Your constructor already assigns $persons_name to the attribute, but if you left the var $name; out, the rest of your script wouldn't really know that there's such an attribute in your class. Additionally if your constructor didn't assign it right away, person::get_name() would attempt to retrieve an undeclared $name attribute and trigger a notice.
As Brenton Alker says, declaring your class attributes explicitly allows you to set their visibility. For instance, since you have get_name() as a getter for $name, you can set $name as private so a person's name can't be changed from outside the class after you create a person object.
Also, attempting to assign to undeclared class attributes causes them to be declared as public before being assigned.
it is very useful.
imagine you write a bunch of person objects with different names in an array and you will call the names of all objects at another place in your website. this is just possible when you store the name of every particular person.
If i understand correctly, you don't need to declare var $name. You can use PHP's magic methods instead, in this case __set and __get.
Edit: there's a small introduction about magic methods # Nettuts.
I need to clear some OOPS concepts in PHP.
Which is faster $this->method(); or self:method();
I know the concept of static keyword but can you please post the actual Use of it. Since it can not be accessed by the instance, but is there ant benefit for that?
what is factory? How can i use it?
What is singleton? How can i use that?
What is late static binding?
http://www.php.net/manual/en/oop5.intro.php
I have gone through below link but I am not getting clear with it.
1) Which is faster $this->method(); or self:method();
I set up a simple loop which calls the same method 1,000,000 times using both methods and the results are pretty much equal (in reality -> was slightly faster but by an extremely short margin)
2) I know the concept of static keyword but can you please post the actual Use of it. Since it can not be accessed by the instance, but is there ant benefit for that?
What do you mean not accessed by the instance?
public static $x;
public static function mymethod() {};
can be accessed through self::$x and self::mymethod().
There are multiple uses of static members, none of them very nice. They can be used to create singleton objects, the can be used to invoke class methods without needing to instantiate the class (for something like a bootstrap object)
3) what is factory? How can i use it?
Factories are objects used to abstract code needed to instantiate objects of a similar type. For example if you have a website which uses a hierarchy of users, each user level might have its own class. Fundamentally all the user classes will be created in the same way but there may be one or two class specific actions required.
A factory object would contain all this instantiation code and offer a simple interface to the developer. So you could use $oFactory->createUser() and $oFactory->createManager() instead of repeating yourself in multiple areas of your code.
4) What is singleton? How can i use that?
A singleton is a class that can have one and only one instance at any one time. The basic idea is that you would use a static method and a static variable to check if the object has already been instantiated.
You would use a singleton where it is important to only have one instance of a class, for example a security model may be a singleton since you want to make sure that there is only one place in your code responsible for authenticating users, a database abstraction could be a singleton if you only require one db connection (it wouldn't make sense to keep connecting to the same server and the same database for each query)
Pre-PHP5.3 singletons have some fundamental flaws since the absence of late static binding means that you can't easily extend a base singleton class.
5) What is late static binding?
Late static binding is a delay in class resolution for static methods to improve their use in OO (derived classes in particular). LSB allows self:: or __CLASS__ to resolve to the current class now instead of the class that they are defined in.
For example in earlier versions of PHP....
class parentClass {
public static function someMethod() {
echo( __CLASS__ );
}
}
class childClass extends parentClass {
}
$oObject = new childClass();
$oObject::someMethod();
would output parentClass to the browser, using LSB childClass would be output.
This is useful for many things including singletons, since the class is resolved properly it is now possible to define a singleton base class and have other objects extend it with expected results.
2) Static Key word: Unlike the methods
and data members used in OOPS where
the scope is decided by access
specifiers, the static
methods/attributes are available as a
part of the class. So it is available
to all the instance defined for the
class. To implement static keyword
functionality to the attributes or the
methods will have to be prefix with
“static” keyword. To assign values to
static variables you need to use scope
resolution operator(::) along with the
class name.
example:
< ?
class ClassName
{
static private $staticvariable; //Defining Static Variable
function __construct($value)
{
if($value != "")
{
ClassName::$staticvariable = $value; //Accessing Static Variable
}
$this->getStaticData();
}
public function getStaticData()
{
echo ClassName::$staticvariable; //Accessing Static Variable
}
}
$a = new ClassName("12");
$a = new ClassName("23");
$a = new ClassName("");
?>
Output:
12
23
23
Explanation:
* Here i have declared static variable $staticvariable
* In the constructor i am checking and value and then assigning the value
to the static variable
* Finally the getStaticData() method will output the static variable
content
1) Which is faster $this->method(); or self:method();
Answer: "self" (not $self) refers to
the type of class, where as $this
refers to the current instance of the
class. "self" is for use in static
member functions to allow you to
access static member variables. $this
is used in non-static member
functions, and is a reference to the
instance of the class on which the
member function was called.
Because "this" is an object, you use
it like: $this->member Because "self"
is not an object, it's basically a
type that automatically refers to the
current class, you use it like:
self::member
What is singleton? How can i use that? php
In software engineering, the singleton pattern is a design pattern used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects (say, five). Some consider it an anti-pattern, judging that it is overused, introduces unnecessary limitations in situations where a sole instance of a class is not actually required, and introduces global state into an application
Example:
final class Singleton
{
protected static $_instance;
private function __construct() # we don't permit an explicit call of the constructor! (like $v = new Singleton())
{ }
private function __clone() # we don't permit cloning the singleton (like $x = clone $v)
{ }
public static function getInstance()
{
if( self::$_instance === NULL ) {
self::$_instance = new self();
}
return self::$_instance;
}
}
$instance = Singleton::getInstance();
5) What is late static binding?
Refer: Late Static Binding
What Is Factory?
refer Design Pattern
I have gone through below link but I
am not getting clear with it.
The official documentation is rich and comprehensive but some users find it hard to understand. If you are unable to grasp that, I would suggest you to go through this excellent tutorial at phpro.org (a great great resource on php topics):
Object Oriented Programming with PHP
The tutorial has been written in simple language with good real world examples, very helpful to those having problem in understanding the OOP concepts.
You are asking a pretty general question. Those are really basic concepts, so you should try to research a bit further, using also general OOP tutorials and reference.
Just to provide some hints: most of your question refer to the concept of "static". You need to understand the difference between a Class and an Instance of a class. This is the key concept.
A Class is the blueprint to create an instance. You have only one Class, but multiple Instances of it. To create an instance you use the "new" keyword, and give a name to the instance ($x = new A()); But you can have methods and fields which do not require a class instance to be run or accessed. The Class holds them, they are above any instance, they can not access any properties or methods which are not static themselves. They are useful because they can hold data and functions which are global (if you have a static variable, it'll be the same across the entire execution, wherever it is called).
I would strongly recommend you to read a couple a book on the subject. I would personally recommend PHP Object-Oriented Solutions by David Powers. This is in my opinion the best introduction to Object-Oriented coding in PHP for newcomers. You need the core knowledge before you can deploy programming patterns efficiently.
If you are really looking to understand design patterns, i would recommend Design Patterns by Christoffer G. Lasater. I've struggled to understand some of these patterns myself, and he explains them in a reasonable understandable way for the average programmer. It is written for Java, but the differences are not really that big.