quick question:
Is it considered bad practice to set something in a Construct function like so:
Class whatever {
$var = "";
public function __construct($var){
$this->var = $var;
}
//And then return it in another function like
public function getVar(){
return $this->var;
}
}
Yes, it is bad practice since you not declare $var and not are using a setter method. The meaning with getter and setter methods completely vanyshes when you not declare the variable, and not declare it private or protected. Then you could just go with $class->var=something.
Class whatever {
private $var;
public function __construct($var){
$this->setVar($var);
}
public function setVar($var){
$this->var = $var;
}
public function getVar(){
return $this->var;
}
}
no it is a good practice .
suppose you have 20 fields , and you must fill them to use class correctly .
good practice is to initialize them in the construction . if you use setter you must call 20 methods .
You have good answers, but I'll give you a rundown on some more info
what is the constructor for?
Use a constructor in your classes if your class instances need initialization
a getter for variables set in the constructor could be useful as a way to find out how the instance was initialized
setters
You need these when you need to modify the behaviour of your instance, or when you want to load data into it
getters
The only way to retrieve the contents of the instance (public properties are not encouraged due to a plethora of reasons)
My example
Feel free to do what you wish with this, it's only an example and it's obviously not doing anything. If you want to ask anything about this, please do
<?php
class AnExampleClass {
// this is convenient sometimes but I don't recommend it
public $public = '';
protected $protected;
private $private;
public function __construct($private, $protected){
$this->private = $private;
$this->setProtected($protected);
}
public function getPrivate(){
return $this->private;
}
public function getProtected() {
return $this->protected;
}
public function setProtected($protected) {
// only allow boolean
$this->protected = (bool)$protected;
}
public function __get($name) {
// read the manual on this magic
}
public function __set($name, $value) {
// read the manual on this magic
}
}
Related
I wrote the following example class:
class Test {
public $baseSymbol;
public $counterSymbol;
public function __construct($baseSymbol,$counterSymbol) {
$this->baseSymbol = $baseSymbol;
$this->counterSymbol = $counterSymbol;
}
public static $var = new Test("CV", "SWR");
}
As you may noticed, I want that the attribute $var of the class Test become a Object of type Test. I did the same thing easily in Java, as a public static variable, but in PHP it's not working...Is there any alternative for what I'm trying to do?
Because you cant set complex types within the definition of the class variables, the only way I can perceive doing this in PHP is to use the magic of procedural code ( Joke ). Now It's important to note that within the file the class exists in you can certainly do something like this.
class Test {
public $baseSymbol;
public $counterSymbol;
protected static $var;
public function __construct($baseSymbol,$counterSymbol) {
$this->baseSymbol = $baseSymbol;
$this->counterSymbol = $counterSymbol;
}
public static setVar(Test $var ){
self::$var = $var;
}
}
Test::setVar( new Test() );
This is pretty standard fare, but as mentioned above by placing the setting code within the class, when the file is loaded the setting is done immediately and pre-loads the class instance before anything else can be done.
This is simply a consequence of not being pre-compiled. When the class is loaded there is no guarantee that a complex object that is required is present, and because of that PHP plays it safe and restricts this ability.
I did change the variable to be protected to keep it encapsulated, this of course is optional. I also added type casting which will insure that only an object or descendant object of Test is used as the input.
Probably not the most favorable solution but one that will work. One last thing you could do just to make sure if you really want to keep it from being changed is to change the setter like this.
public static setVar(){
if( !self::$var ){
self::$var = new Test();
}
}
This way you just call the method with Test::setVar() and once it's got a value it always returns not false, so it will not be changed latter.
One last note, if you truly want a copy of the class itself, this is the Test class with a static instance of itself ( like a singleton ) then do this instead of using the name
public static setVar(){
if( !self::$var ){
self::$var = new self;
}
}
Now to wrap that into a singleton, you can do the class like this.
final class Test {
public $baseSymbol;
public $counterSymbol;
protected static $var;
//no constuction
private function __construct($baseSymbol,$counterSymbol) {
$this->baseSymbol = $baseSymbol;
$this->counterSymbol = $counterSymbol;
}
//no cloning
private function __clone(){}
public static getInstance(){
if( !self::$var ){
self::$var = new self('%', '#');
}
return self::$var
}
}
$Test = Test::getInstance();
Here I go rambling, now ponder saving the instance in an array with a key. Then you can have a Multiton ( is that a thing? );
public static getInstance($type, $baseSymbol,$counterSymbol){
if( !isset(self::$var[$type] )){
self::$var[$type] = new self($baseSymbol, $counterSymbol);
}
return self::$var[$type];
}
It makes a great database class, just saying.
You could access $var via a getter and initialize it there on demand:
private static $var;
public static function getVar()
{
if (null === self::$var) {
self::$var = new Whatever();
}
return self::$var;
}
I am currently digging into the basics of php class / constructor.
I understand how a constructor works but not why I should use it.
For example when I have a constructor like this:
function __construct($arg1, $arg2){
$this->name = $arg1;
$this->speed = $arg2;
}
Why should I use __constructor and not a simple callback like:
function foo($arg1,$arg2){
$this->name = $arg1;
$this->speed = $arg2;
}
Thank you
Doing
$obj = new Class($var1, $var2);
And
$obj = new Class($var1, $var2);
$obj->foo($var1, $var2);
Have the same end result
By forcing values to be passed on the constructor, class can define Mandatory values it should have in order to construct a class. As in the later case, one can ignore foo.
Having a method to initialize means, one ends up having different method names, foo, init etc, constructor avoids this
The constructor is always called on object instantiation and is a known pattern.
Your second example isn't (if it's intended to perform a similar initialisation role as the constructor).
<?php
class abc {
function __construct($arg1, $arg2){
echo $arg1.' '.arg2;
}
}
$obj = new abc('manish','jangir');
?>
It will print "manish jangir" automatically when the object is created
The main purpose is to keep your code clean. With placing your initialization in the constructor you can kan be sure the variable to be used in the other function will be in valid state for example :
class Foo{
private $number;
public function setNumber($number) {
$this->number = $number;
}
public function getNumber() {
if ($this->number=== null) {
throw new RuntimeException("The Number is Null !");
}
return number;
}
}
this is the class with constructor
class Foo{
private $number;
public function __construct($number) {
$this->number = $number;
}
public function getNumber() {
if ($this->number=== null) {
throw new RuntimeException("The Number is Null !");
}
return number;
}
}
with constructor you can be sure the number will be initialized. I hope my answer is clear enough but if you have another question about my answer feel free to ask in the comment :)
I can write classes which do the exact same thing two different ways;
class Simple {
private $var;
public function __construct() {
$this->var = $this->setVar();
}
private function setVar() {
return true;
}
}
Or
class Simple {
private $var;
public function __construct() {
$this->setVar();
}
private function setVar() {
$this->var = true;
}
}
When would I use one over the other? I have seen many different php applications use the two different types. But there seems no general guideline to follow, or does it even matter for that fact?
Neither of these look like correct property setters to me. A property setter should take a parameter, and assign the parameter value to the property:
class Simple {
private $var;
public function setVar($val) {
$this->var = $val;
}
public function getVar() {
return $this->var;
}
}
Setters should set, not return. This should need no more explanation.
I have a class 'base' and a class 'loader', which looks like this.
class base {
protected $attributes = Array();
public $load = null;
function __construct() {
$this->load = loader::getInstance();
echo $this->load->welcome(); //prints Welcome foo
echo $this->load->name; //prints Foo
echo $this->name; //doesnt print anything and i want it to print Foo
}
public function __get($key) {
return array_key_exists($key, $this->attributes) ? $this->attributes[$key] : null;
}
public function __set($key, $value) {
$this->attributes[$key] = $value;
}
}
class loader {
private static $m_pInstance;
private function __construct() {
$this->name = "Foo";
}
public static function getInstance() {
if (!self::$m_pInstance) {
self::$m_pInstance = new loader();
}
return self::$m_pInstance;
}
function welcome() {
return "welcome Foo";
}
}
$b = new base();
Now what I want is a way to store variables from loader class and access them from base class using $this->variablename.
How can I achieve this? I don't want to use extends. Any idea ?
I don't feel like you've fully understood what coding the OOP way means. And usually Singletons are code smells so I'll just warn you:
There's probably a better way of accomplish you goal. If you provide more informations we will help you out. In its current form the answer is the following; just remember that I higly discourage its implementation in your code.
Assuming that you want to access only public (and non static) loader's variables as this->varname in the base class you should just insert this line in the beginning of the base class constructor:
$this->attributes = get_object_vars(loader::getInstance());
This will basically initialize the attributes array with all the loader public vars so that via your __get() method you can access its value.
On a side note, take a look at Dependency Injection design pattern in order to avoid using Singletons.
Your __get/__set methods access $this->attributes but not $this->load.
You could e.g. do something like (pseudocode)
function __get($key) {
- if $attribute has an element $key->$value return $attribute[$key] else
- if $load is an object having a property $key return $load->$key else
- return null;
}
see also: http://docs.php.net/property_exists
You can make static variable and then you can access this variable from anywhere
public statis $var = NULL;
and you can access it like this
classname::$var;
If I have two public functions and I want to pull a variable from one inside of another, what is the best way to accomplish this? I know about 'global' but this method seems like it could cause me problems down the road.
Imagine I have something like this:
class myCMS {
public function process_apples() {
$a = $_POST['$apples'];
}
public function display_apples() {
echo $a;
}
}
How would I go about using display_apples() to report $a from process_apples()? Im new to PHP, so feel free to let me know if I am violating some best practicing for organizing my code.
If you have two methods in a class, and want a variable to shared between them, you should use a class property -- which is kind of a variable that's inside a class.
Your class would then look like this :
class myCMS {
protected $a; // declare the property (won't be visible from outside the class)
public function process_apples() {
$this->a = $_POST['$apples'];
}
public function display_apples() {
echo $this->a;
}
}
And a couple of notes :
You need to use $this->property_name to access a property
Not related, but you should generally no use $_POST from inside your class : it makes your class dependent on external global variables -- of course, up to you to determine whether it's a problem or not.
You would have:
class myCMS {
private $a;
public function process_apples() {
$this->a = $_POST['$apples'];
// process
}
public function display_apples() {
echo $this->a;
}
}
Since you're using a class, you could make a private class variable, like this:
class myCMS {
private $a;
public function process_apples() {
$this->a = $_POST['$apples'];
}
public function display_apples() {
echo $this->a;
}
}