Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm learning PHP so bear with me. Both of these classes set either a public or private variable, before it is used. Why is this?
class test {
public $name; // called here
public function __construct ($name) {
$this->name = $name;
}
}
$testing = new test('Hello');
echo $testing->name;
and:
class db_link {
private $link; // called here
public function __construct ($database_name) {
$link = mysql_connect ("localhost", "your_user_name", "your_password");
mysql_select_db ($database_name, $link);
$this -> link = $link;
}
function query ($sql_query) {
$result = mysql_query ($sql_query, $this -> link);
return $result;
}
function __destruct() {
mysql_close ($this -> link);
}
}
$db = new db_link ("MyDB")
$result = $db->query ("Select * from MyTable")
When you are declaring a class as in your example, you are setting up the skeleton for not only what it is, but what it CAN be. The declaration should really include anything and everything that will ever be inside the object - whether or not it will always be used.
In this case it's like saying the object can have hands and fingers, but not all the instances of the object will actually have them.
Although PHP allows some really interesting code (like creating a new property the first time that a value is assigned to it) even if it isn't part of the original object, it's generally considered bad form - and makes it almost impossible to track down errors in the code later.
I can't more strongly suggest only ever using properties that are declared and not just adding things on the fly.
This is to initialize the variable and explicitly set it to public or private so you don't have to hunt through the code for the information.
Variable initialization is a common programming practice in many languages.
They're declaring these variables to be members of the class. If you declare a variable inside of a function, it only exists within the functions 'namespace.' Once that function ends, the variable is deleted. Declaring external to functions allows the variables to inhabit the class' namespace, which means they are accessible to any functions that are methods of the class.
Quick Edit: this also means that the variables will be inherently tied to the class so instances of the class will contain those variables allow them to be accessible and modifiable through accessors and mutators. All in all, it's a very sound method both for reliability and accessibility.
You can declare your member variable anywhere, e.g. this will work:
class test {
public function __construct ($name) {
$this->name = $name;
}
public $name; // member variable $name
}
$testing = new test('Hello');
echo $testing->name;
However it is much more clear if you declare your member variables at the top of the class. Why? Because it is just trivial to be able to clearly see what variables a class is using...
I think I know what you're asking. This is related to Scope.
The variables that are passed to the constructor are available only until the constructor function completes. To register the variables as members of the object you need to assign them to a parameter of the class. Hence:
public $name; // called here
public function __construct ($name) {
$this->name = $name;
}
You can name the variable that is passed to the constructor anything you like (e.g. __construct($argument); $this->name = $argument;).
You're really just telling the constructor to expect a variable when the object is created. It is a common convention to name the variables passed to the constructor the same of the property name to help with readability, but there is no name conflict as the constructor variable does not share scope with the object parameters. the logic of doing this is that it is easier to understand where the variables passed to the constructor are going to be assigned.
so __construct($name) and public $name; ($this->name) are two completely separate pieces of memory .
I hope this helps. I remember what it was like trying to get my head around things like this.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Can you give me an example that consist the function __construct and how that code would be if we convert it into procedural php? Maybe this is a kind of dummy question for you, but for me who never learning php oop before really got confused when i met this new function.
For example, in this code, function _construct used to instantiate a new class.
Class Car{
private $brand;
private $type;
public function __construct($merk, $type){
$this->brand= $brand;
$this->type = $type;
}
public function getCar() {
return "<strong>Brand:</strong> " . $this->merk . "<br /> <strong>Type:</strong> " . $this->type;
}
}
But I'm found new example which only contain this code :
Class Game{
public function __construct()
{
echo "Blah";
}
}
Why on the last example, function __construct just contain the word echo "Blah" not contain this code too --> $this->whatever word ?
The __construct method is usually the method called in a class when an instance of that class is created (called an object). The method is called the constructor because it constructs the object, but that doesn't mean you must use the method to do so.
The point of the method is to set the variables of the object to their inital values, which may be a primitive type such as an integer, or perhaps an instance of another class. If the variables are to be something other than a default value, the __construct method can accept arguments to set the values of the variables.
You don't have to set the variables using the constructor method, nor is it the only thing you can do. You could, for example, print a success message or call another method, either in that class or elsewhere. So your two examples are both valid. The first is how you would expect the constructor to be used, but the second is still vaild. Like I said, __construct is the method that is called on creation of the object, which doesn't mean you have to use it for the intended purpose.
In PHP, it is not required to have a constructor method in a class, but in many other object orientated programming languages, such as Java, if a constructor is not present then it will produce an error at compile time. This is because PHP is what is know as a weakly typed language, which has many pros and cons which you can research further.
Because __construct is one of the magic methods specifically used in a PHP class, it cannot be converted into procedural code. To call the method with arguments, when you assign a class in your code you should give your arguments in the creation statement, like this;
$object = new MyClass($arg1,$arg2);
You cannot call the constructor from outside the class, other than when creating a new object. The only exception to this is a child class (ie, a class that extends another class) can call the constructor of its parent using parent::__construct();.
The constructor is meant for to instantiate a new Class (not neccessarly though) like the example below:
<?php
Class Car{
private $brand;
private $type;
public function __construct($brand, $type){
$this->brand= $brand;
$this->type = $type;
}
public function getCar() {
return "<strong>Brand:</strong> " . $this->merk . "<br /> <strong>Type:</strong> " . $this->type;
}
}
$car= new Car('Audi', 'A3');
echo $car->getCar();
/* Will return:
Brand: Audi
Type: A3
*/
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Access global variable from within a class
I want to fortify my knowledge in PHP. But most of the time I have trouble understanding with scopes. I am not sure when to use $this and global declaration keyword on my functions.
This is just an example class I just omitted the __construct()
class myClass{
public myVariable;
public function1() {
$this->myVariable=1;
}
public function2(){
global $myVariable;
$myVariable=1;
}
}
Which one is the best approach to use when assigning pre-declared variables inside a function? I am confused somehow by the different books by major publishers in PHP. I am not sure if I am asking the correct question or somehow relevant.
First off, thats not valid PHP, as Jared Farrish already said. Its public $myvar instead of public myvar. Variable names always begin with $.
When you declare a variable in a class:
<?php
class A
{
private $var;
}
That variable will be automatically available in all methods if accessed through $this (unless the method static, but that is another story). So this would work:
<?php
class A
{
private $var;
public function foo () {
// This works
$this->var = 1;
// This is a completely different thing and does not change
// the contents of A::$var
$var = 1;
}
}
Now global is a different thing altogether. In PHP, you cant do this:
<?php
$global_a = 123;
function myfunc ()
{
// You wont actually change the value of $global_a with this
$global_a = 1234;
}
echo $global_a; // still 123
You'd think this would work, but global variables aren't automatically available to functions. This is where global comes in:
<?php
$global_a = 123;
function myfunc ()
{
global $global_a;
$global_a = 1234;
}
echo $global_a; // now it will be 1234
I suggest you read about variable scope in PHP and then you can go on to OOP in PHP.
PHP is a very quirky language. Just because something works in most languages in a certain way doesn't mean it will work in PHP. Most of the times, it wont. So its best to educate yourself as much as possible.
Hope this helps
Which one is best often depends on the situation. In general it's best to avoid global variables as they bring risks with them of not knowing exactly where they're used.
Using a class variable is a good option if the variable is specific to that instance of the class. (You will have to prefix it with a $, though. I.e., public $myVariable;).
If the variable is only relevant to the function and instances outside the class, you'd do best to pass it as an reference. This is done by adding an & before the $ in the parameter space. I.e.:
public function3(&$myVariable) {
$myVariable = 1;
}
Or alternatively just return the value you wish and set it outside the function. I.e.,:
class MyClass {
public function3() {
return 1;
}
}
$myObject = new MyClass();
$myVariable = $myObject->function4();
try to avoid passing global variable,as there are many good reasons for that:
Reusing parts of the script is impossible :
If a certain function relies on global variables, it becomes almost impossible to use that function in a different context. Another problem is that you can’t take that function, and use it in another script.
Solving bugs is much harder :
Tracking a global variable is much harder than a non-global variable.
Understanding the code in a year will be much more difficult :
Globals make it difficult to see where a variable is coming from and what it does.
Now your questions:
Which one is the best approach to use when assigning pre-declared variables inside a function?
You can pass them by value or reference inside a function
By value
$firstVar = 1;
function abc($firstVar){
echo $firstVar ; // will give you 1
}
By reference
function abc(&$firstVar){
$firstVar = 3; // this will give utility to change that variable even
echo $firstVar ; // will give you 3
}
Now where to use $this variable:
$this is used to refer to the current object.
example:
class abc{
private $firstVar;
function abc(){
$this->firstVar = 2;
}
}
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.
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.
First of all, I do not want to extend a class. I would ideally like to do this.
public function __construct() {
/* Set Framework Variable */
global $Five;
$this =& $Five;
}
I have a system where the variable $Five is a container class which contains other libraries. I could assign this to a local variable of Five... i.e.
public function __construct() {
/* Set Framework Variable */
global $Five;
$this->Five = $Five;
}
However, the reason why I am trying to avoid this is that function calls would be getting a little long.
$this->Five->load->library('library_name');
Its a little ugly. Far better would be.
$this->load->library('library_name');
What is the best solution for this?
I think that
$this->Five->load->library('library_name');
is going to be your best option unless you decide to have the class extend the helper class. AKA
class Something extends Helper_Class
However, this means that Helper_Class is instantiated every time you instantiate a class.
Another method would be to have a pseudo-static class that assigned all of the helper classes to class members
public function setGlobals($five)
{
$this->loader = $five->loader;
}
Then just call it
public function __construct($five)
{
someClass::setGlobals($five);
}
If $Five is a global, you could just global $Five everytime you want to use it, but putting that at the top of every function just seems like bad coding.
Also, I'd just like to do my public service announcement that Global variables are generally a bad idea, and you might want to search 'Dependency Injection' or alternative to globals. AKA
public function __construct($five);
instead of
global $five;
Globals rely on an outside variable to be present and already set, while dependency injection requests a variable that it is assuming to be an instance of the Five class.
If you are running PHP 5.1 (Thanks Gordon), you can insure the variable is an instance of the FiveClass by doing this:
public function__construct(FiveClass $five);
$this is a reference to the current instance of the class you are defining. I do not believe you can assign to it. If Five is a global you ought to be able to just do this:
$Five->load->library('library_name');
You might wanna go with some kind of implementation of the dependency injection pattern:
Dependency injection (DI) in computer
programming refers to the process of
supplying an external dependency to a
software component. It is a specific
form of inversion of control where the
concern being inverted is the process
of obtaining the needed dependency.
See also the documentation for the symfony DI container. I can highly recommend this DI container implementation if you want to improve the way you handle your 'globals'.
You could also have a read of this question on 'best ways to access global objects'.
How about making the relevant data members and methods of Five static class members? This
$this->Five->load->library('library_name');
would become this
Five::load->library('library_name');
and you wouldn't have to pass &$Five around everywhere.
You cannot overwrite $this (like e.g. in C++) but you can easily build an aggregate using __call() for method calls and __get(), __set(), __isset() for properties.
Example for __call():
class Five {
public function bar() {
echo __METHOD__, " invoked\n";
}
}
class Foo {
protected $Five = null;
public function __construct(Five $five=null) {
if ( is_object($five) ) {
$this->Five = $five;
}
}
public function __call($name, $args) {
// there's no accessible method {$name} in the call context
// let's see if there is one for the object stored in $five
// and if there is, call it.
$ctx = array($this->Five, $name);
if ( !is_null($this->Five) && is_callable($ctx) ) {
return call_user_func_array($ctx, $args);
}
else {
// ....
}
}
}
$foo = new Foo(new Five);
$foo->bar();
prints Five::bar invoked.
In my opinion the biggest draw back is that it is much harder to see "from the outside" what the object is capable of.
I'm pretty sure you can't reassign $this, as it's one of those special things that looks like a variable in PHP, but is treated slightly differently behind the scenes.
If your concerns are the semantics of your method calling getting too long, I'd make load a method call instead of an object property
$this->load()->library('library_name');
public function load()
{
return $this->Five;
}
maybe better for you will be to use PHP Magic Methods?
http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods