I just started using OOP / CodeIgniter. I want to get assign the form input to variables. I wonder which one I should use $this -> var or $var and how they differ from each other? Thanks.
For example
$agree = $this -> input -> post( 'agree' );
OR
$this -> agree = $this -> input -> post( 'agree' );
Both will work fine like:
if ($agree) { }
OR
if ($this -> agree){ }
Thanks
It's a matter of scope
<?php
class Example extends CI_Controller
{
private $agree1;
public function __construct()
{
parent::__construct();
}
public function index()
{
$agree2 = $this->input->post( 'agree' );
$this->agree1 = $this->input->post( 'agree' );
// within this context both are accessable
// these will print the same
var_dump($agree2);
var_dump($this->agree1);
// call the helper function
$this->helper();
}
private function helper()
{
// within this context $agree2 is not defined
// these will NOT print the same. Only the 2nd will print the content of the post
var_dump($agree2);
var_dump($this->agree1);
}
}
?>
This is really a matter of preference when it comes to extra local variables. As general guidance, I would use $var if the variable is only pertinent to the method, and $this->var if it makes sense for other methods to use this variable too.
If you are just collecting the input and handling it in that method, I would just use a local variable. Class members are normally used for things relevant to the class/object, for example a class representing a vehicle might have a $number_of_wheels variable.
I'm assuming that you're talking about what to use inside a controller/action pair?
$this->var actually refers to a property of your controller class named var.
$var means that it's a locally (function) scoped variable
If you do not specifically want to access a class property, don't use $this. Just use $var and have it accessible only within the scope of the function.
If you are actually referring to a class property and you want this property to be acessible by all methods in your class, make sure you declare it in your class definition on top.
It depends on whether you want to set a local variable or an object variable.
You should have your object variable declared at the beginning of the class (e.g. private $var) - they are accessible from different methods across the class.
Local variable is accessible only in the scope of current method.
If you use $this->var then you are referring to a class variable. If you are assigning it to just $var then you are referring to a local variable. I am gussing you need to make use of the following if you don't need the form values to be available to other methods:
$agree = $this->input->post('agree');
$this->agree) if you're going to use it in other functions of the class, $agree if using it within the current scope, meaning inside the function making it a local variable only.
I think only $this->agree works, however, I have not tested this.
Ad#m
Related
Take, as an example, this abstract class from a project I am working on. (minus all the really interesting bits).
abstract class col_meta extends meta {
protected $col_obj;
public function inject_object(&$obj);
public function &get_object(){
return $this->col_obj;
}
}
I understand that the inject_object method receives $obj as a reference but if I want the class to assign it to a protected variable do I need to assign by reference again?
like this:
class foo extends col_meta {
public function inject_object(&$obj){
$this->col_obj = &$obj;
}
}
Or, having only been given a reference, do I need to simply copy the reference into the protected variable?
class bar extends col_meta {
public function inject_object(&$obj){
$this->col_obj = $obj;
}
}
I've been tying my mind up in knots trying to work this out as they both seem right.
By definition, by reference is "by reference"; meaning that if the value is changed in the function, it's changed in the calling script.
However - because it provides better performance - if you pass "by value", PHP still passes the reference to the function, but creates a copy (by value) if you change the value in the function.
Note that objects are always effectively "pass by reference", because your object variable is actually a pointer to the object, so any changes to an object inside the function will be reflected outside the function as well.
Don't pass by reference unless you explicitly want a variable changed inside the function to be changed outside the function as well.
If you want a "copy" of the object inside you class, rather than the reference; then use clone to create a copy.
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 adapted a very simple View class to pass variables from Controller to View so that in the View I can call the variables directly e.g.
<?php echo $name; ?>
and not
<?php echo $this->name; ?>
All the view vars are stored in an associative array called vars e.g. $vars['name'] = "test" and have __set function setup to assign vars e.g.
$v = new View;
$v->name="test";
$v->out();
So in the out() function which passes the variables and includes the view HTML I added:
foreach($this->vars as $key=>$val) {
$$key=$val;
}
include $this->view_file;
I then tested what would happen if I used $this in the template and added a corresponding variable like
$v->this = "test_this";
My assumption was that either the code will fail because $this cannot be reassigned or that even if it reassigned - see here - the code will fail because $this has been reassigned so
include $this->view_file;
won't work!
Instead, it worked.
$this, when called directly either using echo $this; or var_dump($this); equals "test_this" but $this->view_file still points to the original value!!
How can this be?
I then retested using extract($this->vars, EXTR_OVERWRITE) and $this didn't get touched!
In general, what would be the right approach to pass variables to the view and avoid collisions in the function
function out($view, $toString = false)
{
extract($this->vars);
include $view;
}
and vars might have a var called view or "this" or maybe the template will use the $view var.
Don't worry, just make sure not to assign a var called view.
Use long variable names in out() function, like $longVarNameSoThatThereWillNotBeCollisions.
Assign all vars that are needed for function to $this->temp: $this->temp['view'] and then unset($view) - and as for $this - who in their right mind would use a variable called $this in View!
To explain why you are still able to access an objects properties, even though you've managed to circumvent the protection of reassigning $this, you have to look at the opcodes generated for the compiled script.
Object properties are accessed using the FETCH_OBJ_R opcode.
When you write code such as
$myObject = new testClass;
$myObject->property
The compiled code generates FETCH_OBJ_R with two parameters. The first is the variable containing the object, and the second is the name of the property.
If you use the Vulcan disassembler, the output might look like the following:
FETCH_OBJ_R $1 !1, 'property'
$1 is where the return value is stored, and !1 is the variable containing the object.
However if you access the property using $this the generated output is slightly different.
FETCH_OBJ_R $1 'property'
The opcode with one parameter resolves the property lookup to the object from within which it was called.
So the answer to your question, $this->property was resolved at compile time. Even though you broke $this, the location of property had already been decided.
This interested me a bit and it seems you're right, there may well be a bug when using variable-variable assignment to $this.
As you rightly said:
<?php
$var = 'this';
$$var = 'hello';
echo $this;
works, whereas
<?php
$this = 'hello';
echo $this;
doesn't.
Perhaps report it on bugs.php.net and see if there's an official answer to this?
The fact that the existing members of $this still work whilst the actual value of $this is something entirely different should definitely not be happening and must be some form of core issue. The only thing I could think of is that somehow $this is being used as a magic context variable (of course not surprising, it is PHP afterall!) and not an actual 'real' variable. The bug of assignment from a variable-variable (which should obviously not happen!) allows the fact that $this is a faux-variable to be displayed to the developer.
Magicness test:
<?php
class ThisTest {
public function SetAndUseThis() {
$var = 'this';
$$var = 'that';
var_dump($this);
var_dump($this->variable);
var_dump($this->AnotherMethod());
}
public $variable = 'i am a variable';
public function AnotherMethod()
{
return 9.0;
}
}
$inst = new ThisTest();
$inst->SetAndUseThis();
Results in:
string(4) "that" string(15) "i am a variable" float(9)
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.
I m using zend.
I want to define the below code outside the controller class & access in different Actions.
$user = new Zend_Session_Namespace('user');
$logInArray = array();
$logInArray['userId'] = $user->userid;
$logInArray['orgId'] = $user->authOrgId;
class VerifierController extends SystemadminController
{
public function indexAction()
{
// action body
print_r($logInArray);
}
}
But it does not print this array in index function on the other hand it show this array outside the class.
How it is possible.
Thanks.
To access a global variable from inside a method/function, you have to declare it as global, inside the method/function :
class VerifierController extends SystemadminController
{
public function indexAction()
{
global $logInArray;
// action body
print_r($logInArray);
}
}
In the manual, see the section about Variable scope.
Still, note that using global variables is not quite a good practice : in this case, your class is not independant anymore : it relies on the presence, and correct definition, of an external variable -- which is bad.
Maybe a solution would be to :
pass that variable as a parameter to the method ?
or pass it to the constructor of your class, and store it in a property ?
or add a method that will receive that variable, and store it in a property, if you cannot change the constructor ?
print_r($GLOBALS['logInArray']);
http://php.net/manual/en/reserved.variables.globals.php
You can store the user in many ways and access it in more clean manner. You can store it in Zend_Registry and then use Zend_Registry::get('user') where you need to retrieve the user. You can also store it as a parameter of request object, and then in a controller simply do $user = $this->_getParam('user');
If you need access to the user array in many controllers that inherit from the SystemadminController, what you can do is store it as a protected property of the SystemadminController (eg. protected $_user). Then all you need to do in child controllers is access $this->_user.