When should I declare variables in a PHP class?

PhpOop

Php Problem Overview


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?

Php Solutions


Solution 1 - Php

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.

Solution 2 - Php

If you declare a member inside the class you can set its accessibility e.g

private $varname;

Solution 3 - Php

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.

Solution 4 - Php

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.

Solution 5 - Php

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.

Solution 6 - Php

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.

Solution 7 - Php

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;
	}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrewView Question on Stackoverflow
Solution 1 - PhpFederico klez CullocaView Answer on Stackoverflow
Solution 2 - PhpDave ArcherView Answer on Stackoverflow
Solution 3 - PhpMichael MoussaView Answer on Stackoverflow
Solution 4 - PhpArtem BargerView Answer on Stackoverflow
Solution 5 - PhpPaulJWilliamsView Answer on Stackoverflow
Solution 6 - PhpSajidur RahmanView Answer on Stackoverflow
Solution 7 - PhpHoldOffHungerView Answer on Stackoverflow