My question(s) is one of best practices for OOP. Im using Codeigniter framework/PHP.
I have a class:
class Test() {
var $my_data = array();
function my_function() {
//do something
}
}
Is it ok to declare $my_data in the class like that? or should it go in the constructor? Basically every function will be writing to $my_data so in a sense it will be a class-wide variable(global?, not sure about the terminology)
Also, should I use var or private ? is var deprecated in favor of declaring the variables scope?
If you want $my_data to be available to all methods in Test, you must declare it at the class level.
class Test {
private $my_data1 = array(); // available throughout class
public function __construct() {
$my_data2 = array(); // available only in constructor
}
}
var is deprecated and is synonymous with public. If $my_data doesn't need to be available outside of Test, it should be declared private.
If it belongs "to the class", put it in the class. If it belongs "to an instance of the class", put it in the constructor. It kinda sounds like you should be using the session, though.
its fine if you declare the variable outside constructor.
actually codeigniter will not let you give any parameter at your constructor.
and the variable will automatically assigned value when the class is instantiated.
for default, any of php variable and function with in a class will be have a public access.
i don't really thing you need to use access modifier at codeigniter.
the library it self don't define any access modifier.
Related
I don't understand a concept of class in php. I could be wrong.
I looked at a WordPress plugin. The class was defined and the properties of class wasn't created only functions were created.
Consider this example
class a
{
public function show(){
echo "hello";
$this->something = "xyz" ;
// What is this? How can "something" can be used here;
// as it is not defined in the class?
}
}
Then an object of that class was created in another file.
$obj = new a();
$obj->anothersomething = "abc"; // is it possible?
Enlighten me please.
My question is: Can we assign a value to undeclared property of a class?
Default class visibility is public.
However, it is good practice to explicitly declare class method with it's visibility.
class Foo
{
public function a() {}
protected function b() {}
private function c() {}
}
As #SougataBose mentioned, I'd suggest you running through PHP OOP course
Edit:
When it comes to properties - yes. It is possible to create them dynamically. Again, as a good practice, it is recommended to declare all properties in class body.
In this case it's not a function, but a public class method. Normally you need to define it with public/protected/private keyword, but when skipped, it's just public by default. So then in another file you create an instance of this class and call the public method show() which can then use class instance properties direct. Or you can assign these properties from outside using $obj->anothersomething = "xxx", which is not a good practice. All the assignments should be done through setter methods like this $obj->setProperty($value);
I've been looking at some code and am having a hard time working out variable declaration in php classes. Specifically it appears that the code i'm looking at doesn't declare the class variables before it uses them. Now this may be expected but I can't find any info that states that it is possible. So would you expect this:
class Example
{
public function __construct()
{
$this->data = array();
$this->var = 'something';
}
}
to work? and does this create these variables on the class instance to be used hereafter?
This works the same as a normal variable declaration would work:
$foo = 'bar'; // Created a new variable
class Foo {
function __construct() {
$this->foo = 'bar'; // Created a new variable
}
}
PHP classes are not quite the same as in other languages, where member variables need to be specified as part of the class declaration. PHP class members can be created at any time.
Having said that, you should declare the variable like public $foo = null; in the class declaration, if it's supposed to be a permanent member of the class, to clearly express the intent.
So would you expect this: (code sample) to work?
Yes. It's pretty bad practice (at least it makes my C++ skin crawl), but it wouldn't surprise me in the slightest. See example 2 in the following page for an example of using another class without declaring it beforehand. http://www.php.net/manual/en/language.oop5.basic.php It will throw an error if E_STRICT is enabled.
And does this create these variables on the class instance to be used hereafter?
Yep. Ain't PHP Fun? Coming from a C++/C# background, PHP took a while to grow on me with its very loose typing, but it has its advantages.
That's completely functional, though opinions will differ. Since the creation of the class member variables are in the constructor, they will exist in every instance of the object unless deleted.
It's conventional to declare class member variables with informative comments:
class Example
{
private $data; // array of example data
private $var; // main state variable
public function __construct()
{
$this->data = array();
$this->var = 'something';
}
}
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.
I've been looking at some code and am having a hard time working out variable declaration in php classes. Specifically it appears that the code i'm looking at doesn't declare the class variables before it uses them. Now this may be expected but I can't find any info that states that it is possible. So would you expect this:
class Example
{
public function __construct()
{
$this->data = array();
$this->var = 'something';
}
}
to work? and does this create these variables on the class instance to be used hereafter?
This works the same as a normal variable declaration would work:
$foo = 'bar'; // Created a new variable
class Foo {
function __construct() {
$this->foo = 'bar'; // Created a new variable
}
}
PHP classes are not quite the same as in other languages, where member variables need to be specified as part of the class declaration. PHP class members can be created at any time.
Having said that, you should declare the variable like public $foo = null; in the class declaration, if it's supposed to be a permanent member of the class, to clearly express the intent.
So would you expect this: (code sample) to work?
Yes. It's pretty bad practice (at least it makes my C++ skin crawl), but it wouldn't surprise me in the slightest. See example 2 in the following page for an example of using another class without declaring it beforehand. http://www.php.net/manual/en/language.oop5.basic.php It will throw an error if E_STRICT is enabled.
And does this create these variables on the class instance to be used hereafter?
Yep. Ain't PHP Fun? Coming from a C++/C# background, PHP took a while to grow on me with its very loose typing, but it has its advantages.
That's completely functional, though opinions will differ. Since the creation of the class member variables are in the constructor, they will exist in every instance of the object unless deleted.
It's conventional to declare class member variables with informative comments:
class Example
{
private $data; // array of example data
private $var; // main state variable
public function __construct()
{
$this->data = array();
$this->var = 'something';
}
}
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