Is PHP class variable definition necessary? - php

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.

Related

defining class variables in method?

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/

Does PHP allow you to declare a Class variable without setting it up as a member in the Class definition? [duplicate]

I'm new to the OOP paradigm, so there's probably a simple explanation for this question...
Do you always need to declare public object-wide variables in a class? For example:
<?php
class TestClass
{
var $declaredVar;
function __construct()
{
$this->declaredVar = "I am a declared variable.";
$this->undeclaredVar = "I wasn't declared, but I still work.";
}
function display()
{
echo $this->declaredVar . "<br />";
echo $this->undeclaredVar;
echo "<br /><br />";
}
}
$test = new TestClass;
$test->display();
$test->declaredVar = "The declared variable was changed.";
$test->undeclaredVar = "The undeclared variable was changed.";
$test->display();
?>
In this code, even though $declaredVar is the only declared variable, $undeclaredVar is just as accessible and useable--it seems to act as if I had declared it as public.
If undeclared class variables are always accessible like that, what's the point of declaring them all up front?
That variable isn't uninitialized, it's just undeclared.
Declaring variables in a class definition is a point of style for readability.
Plus you can set accessibility (private or public).
Anyway, declaring variables explicitly has nothing to do with OOP, it's programming-language-specific. In Java you can't do that because variables must be declared explicitly.
If you declare a member inside the class you can set its accessibility e.g
private $varname;
You should always declare your member variables and specify their accessibility within your classes. I like to put this information at the end of the class after my functions.
You should define them as soon as you have enough information to do so. Possibly in the constructor or via setter functions.
It is important to do this because it makes life much easier for people working with your code. They don't have to guess where different properties are coming from or why they're there. Also, most (if not all) IDEs will not pick up on class variables unless you've declared them somewhere. Code completion/hints are one of the many benefits of IDEs and without declaring your variables, you will render that functionality useless.
General OOP paradigm of encapsulation says you should not expose your inner state variables out side that means they should be private, that allows you to change an implementation of your class without need to change the code where you make use of it. It's better practice to initialize variables via constructors and getters and setters method of the class.
In general variables should be initialized as soon as you have enough info to do it properly.
If a class variable needs certain info to be sensibly initialized then that info should be passed to the constructor.
Using PHP's syntax to implicitly declare variables at the point of definition is, IMHO a surefire way to introduce bugs - if your class needs a variable then declare it, and use all of the information hiding that OOP affords you.
As Federico Culloca said "That variable isn't uninitialized, it's just undeclared". Also you didn't define any access modifiers for them so that they behaving like public modifier applied to them.
You may already have known, PHP is a loosely typed language. But a programmer should always follow the best practices and define access modifiers manually. It increases code readability.
You can use private modifier for class level variables and provide accessor and mutator methods (Getters and Setters) for them when needed.
TLDR: Only Define What Isn't in The Default/Public
To define or not define global variables within class scope — ultimately, it is a design decision that should be taken to improve code readability, and nothing more. Personally, I don't "define all of these," and I use the default scope of public (Source: PHP.net -> Visibility). I do that until I actually need to change any of them for a particular need.
The Basic Objection
"But shouldn't that be set so we can define public and private as needed?" : If you need to set a global variable's status, then set it. Until you set it, it is public. So, set it when you need it. Don't write code that does nothing with the hope that one day in the future you'll thank yourself -- odds are you may need to completely revamp everything your old self did. And what if you have hundreds of variables all set to the same default instance? How does that help anyone?
Why Avoid Hardcoding the Accessibility Value on Attributes?
At some point, we will be able to configure the default, and then all that code that hard-coded this class accessibility, or that class accessibility, will need to be reprogrammed. In general, hard-coding is bad, and the large amounts of typing/copying-pasting associated with class attribute access definitions is just not worth the result. Use the default.
It's Really All About Style
If all your class variables public and the extra global definitions (100's of them maybe) doesn't help you, then dump them. If they give structure to your code, though, then keep them. It's something done to help the coder, not the compiler.
Which would you rather have to fix?
This?
class basicscript extends baseformat {
public function __construct($args) {
$this->startUp($args);
return $this;
}
}
Or this?
class basicscript extends baseformat {
public $desired_script;
public $desired_action;
public $object_code;
public $object_parent;
public $object_list;
public $script_location;
public $script_name;
public $script_file;
public $script_extension;
public $script_format;
public $script_format_lower;
public $script_args;
public $authentication_object;
public $cleanser_object;
public $query_object;
public $db_access_object;
public $domain_object;
public $language_object;
public $dictionary;
public $time;
public $cookie;
public $formats_object;
public $version_object;
public $redirect_object;
public function __construct($args) {
$this->startUp($args);
return $this;
}
}

When and How to make class variables with PHP?

Newbie question, i have variables inside my class method, do i have to make them class variables where i can access them using $this? If no, please explain when do i use or make a class variables?
private function is_valid_cookie()
{
$securedtoken = $this->input->cookie('securedtoken');
// Checks if the cookie is set
if (!empty($securedtoken)) {
// Checks if the cookie is in the database
$s = $this->db->escape($securedtoken);
$query = $this->db->query("SELECT cookie_variable FROM jb_login_cookies WHERE cookie_variable=$s");
if ($query->num_rows() != 0) {
// Now let us decrypt the cookie variables
$decoded = unserialize($this->encrypt->decode($securedtoken));
$this->login($decoded['username'], $decoded['password']);
return true;
} else {
return false;
}
} else {
return false;
}
}
as you guys can see, i have variables $securedtoken and $decoded = array(), i cant decide if i have to make them class variables and just access them with $this
I actually try to minimize use of class-level variables to cases where they are going to be common amongst multiple methods, or they are going to be referenced from code outside the class (either directly or via getters/setters). If the variable is just needed in local scope for a method, do not pollute the class with it.
You'll want to make class variables when you are trying to share those variables throughout different functions in the class. You'll then need different Access Modifiers (public, private, protected) for these properties depending on whether or not outside code can view them, child classes can view them, or nothing at all.
You do not have to make them instance variables. You can make them static variables too, or constant variables! You use a class variable to describe attributes of a class. ie what a class has.
Its important to get your terminology correct too. You are asking about making the variable and instance variable. A class variable (http://en.wikipedia.org/wiki/Class_variable) refers to a static variable
For your specific example if your two variables are only used in that function you should not make them instance variables. There is no reason to share them accross the class
On the other hand if you need to use them again in other methods or in other places than yes. you should.
Deciding what kind of variable you want and what kind of access is a design decision.
Good places to start are object oriented php overview. http://php.net/manual/en/language.oop5.php
And basic beginner tutorials
http://www.killerphp.com/tutorials/object-oriented-php/
You do, yes. You can declare class variables like this:
class Dog
{
protected $name = 'Spot';
public function getName()
{
return $this->name;
}
}
You can read more about properties (member variables) in the documentation.

php oops: visibility

I'm revising my OOPs concepts in PHP. I have a simple php code here for practising visibility.
When i declare $name as private in Big_Animal,
1)Why it doesn't throw an error when i try to assign a different value for $name from outside the class (ie. $lion->name="King")?
2)Why it doesn't throw an error when i try to reassign $name in Lion class (ie. $this->name="John").
I'm confused coz as per my knowledge, private properties can only be accessed within the class that defines the property.
The other thing i'm not clear about is protected properties. As per my understanding, protected properties can be accessed only within the class itself and its child classes. Can it be accessed by its grandchild classes?
Thank you.
<?php
abstract class Big_Animal{
private $name="Mary";
abstract public function Greet();
public function Describe(){
return "name: ".$this->name;
}
public function __set($name,$value){
$this->name=$value;
}
public function __get($name){
return $this->name;
}
}
class Lion extends Big_Animal{
public function Greet(){
$this->name="John"; //no error for this
return " roar!";
}
public function Describe(){
return parent::Describe()." I'm a Lion!";
}
}
$lion = new Lion();
$lion->name="King"; //no error for this
echo $lion->Describe();
echo $lion->Greet();
?>
Your magic method accessors (__set and __get) are public in the base, abstract class. They are the ones writing to the private data when you access the property directly. Try commenting out the magic methods and see. Then, the output is "name: Mary I'm a Lion! roar!".
Add this as the first statement in Lion::Describe():
echo "Lion's name: " . $this->name . "\n";
As you can see, the output is now: "Lion's name: King". Both $this->name="John"; and $lion->name="King"; are modifying the public property on Lion class' object. It's unfortunate that you can have both public and private properties of the same name, but you can. They are simply different variables (in different scopes).
Protected properties can be accessed from grandchildren. Most of your properties should be protected, unless you have a really strong reason to protect it (therefore using private). Public properties aren't used much in larger projects (depending on your style). I'd prefer to stick with explicit accessors. As a project progresses and becomes more complex, you'll be glad you chose to use accessors for each variable. I prefer to use a generator that will generate the scaffolding accessors for you. It saves a lot of time, cuts down on errors, and makes the creation of accessors a lot cheaper (and therefore more common).
UPDATE (a response to the comment below):
1) and 2) You're not getting errors because you're editing the Public variable in both of the instances that I listed in my 2) above. Try var_dump($lion):
object(Lion)#1 (2) {
["name":"Big_Animal":private]=>
string(4) "Mary"
["name"]=>
string(4) "John"
}
Also, if you explicitly add a private or protected member variable to the Lion class, you will get the error that you expect. I would agree with you that that's not very intuitive, but appears to be the current reality in PHP.
3) http://www.ibm.com/developerworks/opensource/library/os-php-7oohabits/ has an example of writing public accessors for private member variables (although, again, I'd recommend writing public accessors for protected member variables instead).
Because you are using magic method of __set()
__set() is run when writing data to inaccessible properties.
It is also possible to get the value by $lion->name because you also use __get().
To elaborate on my comment... You are using a function called __set, what this does is that every time you try to set a value on an unknown property on this class, this specific function is called.
In your function, you are always changing the private field name, into the value provided. Since this class has access to it's field, this is set.
Even if you wrote $lion->foo = "bar", the name would be set to bar, due to your function __set
I think the answer for your question is here
Abstract methods cannot be private, because by definition they must be
implemented by a derived class. If you don't want it to be public, it
needs to be protected, which means that it can be seen by derived
classes, but nobody else.

Why Directly Accesing property is not recommended in OOPs PHP?

If I have a class "person" with a property $name and its getter(get_name()) and setter(set_name()) methods, then after instantiating the objects and setting the property i.e.
$paddy = new person();
$paddy->set_name("Padyster Dave");
echo "Paddy's full name: ".$paddy->name; //WHY THIS IS NOT RECOMMENDED...
In the above code $paddy->name;WHY THIS IS NOT RECOMMENDED
EDIT
Above code is a sample code without assigning any accessifiers.. Its just to understand the $paddy->name concept
The thing that's weird is that you have a setter, but are leaving the property public. (Assuming there's no __get magic going on.)
You usually want to use getters/setters to get more control over what can be assigned to a property and what can't. Or, you may want to execute code when the property is accessed or changed. In either case, you should force the use of the getters/setters by making the property private or protected, otherwise it's pretty pointless. It's about preventing yourself or others that will use the class from shooting their own foot.
If the setter in your example only sets the value without doing anything else, it's superfluous. If it does do something else that is required whenever the value is set, you have a flaw in your class design since it's possible to change the value without using the setter.
class Foo {
public $bar = 0; // is only allowed to contain numeric values
public function setBar($val) {
if (is_numeric($val)) {
$this->bar = $val;
}
}
}
$obj = new Foo();
$obj->bar = 'some value'; // set a string, which is not allowed
If you'd make $bar protected, that wouldn't be possible.
Because you might someday get rid of the $name member, replacing it with (e.g.) $first_name, $last_name and a fullname() method (not that that's a good idea). Of course, with __get and __set, it doesn't matter so much.
More generally, setting a property might not be so simple as storing a value. Giving direct access to member fields can result in other functions causing an object to be in an inconsistent state. Imagine you store an array that needs to remain sorted; if the array were public, something else could assign an unsorted array to the field.
Exposing public fields would be a bad habit.From a good artical about OO principle in PHP
If anything changes with the object, any code that uses it needs to change as well. For instance, if the person's given, family, and other names were to be encapsulated in a PersonName object, you would need to modify all your code to accommodate the change.
Obviously I'm doing 'bad' things too as I use this sort of code all the time.
But what if $this->name (or as I would do $this->nameFormatted) is constructed like:
protected var $name;
$this->name = $this->getSalutation() . ' ' . $this->nameFirst . ' ' . $this->nameLast;
or something along those lines.
You're using $this->name out in the public context, but it's still constructed in the class and if it's protected it won't be overwritten.
Or am I missing the point and the 'bad' thing is actually set-ting the name in the public scope?

Categories