I am having problems creating a variable with data from another class. Here is what I am doing...
<?PHP
class Customers extends Controller {
private $foo = $this->session->userdata('foo');
}
You probably want something more like this:
class Customers extends Controller
{
private $foo;
public function __construct()
{
parent::__construct();
$this->foo = $this->session->userdata('foo');
}
}
It's hard to know for sure without knowing more about your project.
You can set it with constructor because you are inhering from parent class:
class Customers extends Controller {
private $foo = null;
function __construct(){
parent::__construct();
$this->foo = $this->session->userdata('foo');
}
}
This is not possible: $this doesn't exist at the moment when you define the class, and you can't call functions at all at this point at all.
You will need to assign $foo in the constructor, after $this->session has been initialized. (#konforce beat me to the example.)
Related
I have to different classes in my Slim PHP framework, named OrderController & AddressController. I want to access some function of AddressController inside OrderController to reduce code redundancy.
But can't get a way to do it, I got how to do it in pure PHP setup, but how to do it in Slim PHP framework?
The PHP way to do this is as follows:
class A {
private $xxx;
public function __construct() {
$this->xxx = 'Hello';
}
public function getXXX() {
return $this->xxx;
}
}
class B {
private $a;
public function __construct(A $a) {
$this->a = $a;
}
function getXXXOfA() {
return $this->a->getXXX();
}
}
$a = new A();
$b = new B($a);
$b->getXXXOfA();
How to achieve this dependancy injection in Slim?
Slim PHP Framework
Note: I am using Slim PHP v3
2 solutions come into mind:
-1-
You could also try to have the common functionality in a separate Trait.
-2-
I won't do the
new SecondController($container)
inside the constructor of the FirstController unless you need it at every controller-hit.
I like lazy loading, so it will load only when needed.
If your AddressController and OrderController has same parent class, than move these methods to parent:
class AddressContoller extends Controller {
public function test() {
$this->methodFromParent();
}
}
If not, create new object of that class and call method. Method must be public
class AddressContoller extends Controller {
public function test() {
$order = new OrderController();
$order->publicMethodInOrderClass();
}
}
If your OrderController wants to call a method foo from AccessController, you should think about moving foo somewhere else. That's an good indicator for wrong SRP
There are two possibilities
foo belongs to/is relevant for every Controller and has something to do with controlling: Just move it to the parent class.
foo is relevant to only a few classes: Move it to the class, it belongs to. This could be an helper class, some domain model class, or something else. Maybe you have to intruduce a new class to do this.
After a lot of reseach I finally manage to get a solution! Posting it here so if anyone in future might get help from it:
class FirstController
{
protected $container;
protected $db;
protected $view;
protected $second;
// constructor receives container instance
public function __construct(\Interop\Container\ContainerInterface $container) {
$this->second = new SecondController($container);
$this->container = $container;
$this->db = $this->container->db;
$this->view = $this->container->view;
}
public function LocalFunction(){
$this->second->otherFunction();
//call the functions in other classes as above
}
}
I am really sorry if this is s dumb question and I'm having a brain fart, this just seems like something I should know. If I have a structure similar to below, is there some way to get $fooVar in Class bar. Do I need to find some way to pass $fooVar as a parameter or is there some inheritance there that I can take advantage of? I'd like to avoid passing it as a parameter if at all possible. Class bar extends another class and if I passed t as a parameter I'd have to do some extra work.
Thanks so much for your help.
Class foo{
$fooVar;
$bar = new bar()
}//end foo{}
Class bar extends AnotherClass{
echo $foo->fooVar;
}//end bar{}
First of all I want to say, I just know a bit about php but I think this problem can be adapted to any other OOP based language. So I tried to put some code for you up. Their are 4 different approaches I am aware of. (I want to consider that I didn't test the below code snippets.)
Declare a get-Function
in your superclass to access the value of $fooVar. This has the positiv effect to access the value from any other class which can call the get-function.
Like this:
Class foo{
private $fooVar;
function __construct() {
$bar = new bar();
}
function getFooVar() {
return $fooVar;
}
}
Class bar extends foo{
function __construct() {
private $foo = parent::getFooVar(); //init $foo on instantiation by get-function
}
}
2.
Declare $fooVar as protected
the make $fooVar only accessible by their subclasses.
Class foo{
protected $fooVar;
function __construct() {
$bar = new bar();
}
}
Class bar extends foo{
function __construct() {
private $foo = parent::$fooVar; //init $foo on instantiation by parent
}
}
3. Add $fooVar as parameter
to your subclass constructor. (I am fully aware of that this is not what you want, but I state it here as another solution and for clarification.)
Class foo{
protected $fooVar;
function __construct() {
$bar = new bar($fooVar);
}
}
Class bar extends foo{
function __construct($var) {
private $foo = $var; //init $foo on instantiation with parameter
}
}
4.
Make $fooVar global.
(another solution but not recommanded.)
I think you are going well with the get function. From the last two cases I would advice especially against the last one.
I really hope this is what you are looking for and it helps alot.
In my model, I am extending Zend_Db_Table_Abstract. Inside, I have a protected $_name = 'table_name'.
Now, if I define a constructor, and a private variable private $_var and define it inside the constructor, the model does not work anymore! When I call $this->createRow() or anything, nothing happens! Why is this constructor doing this?!
This is what I have:
<?php
class myClass extends Zend_Db_Table_Abstract
{
protected $_name = 'table_name';
private $_var;
public function __construct($var)
{
$this->_var = $var;
}
public function getById($id)
{
$select = $this->select()->where('id =?',$id);
return $this->fetchRow($select);
}
}
This doesn't work! If I remove the __construct(), and the private variable, then it works! Why?
Thanks
If you override the constructor of Zend_Db_Table_Abstract, you should probably call the parent constructor:
class MyClass extends Zend_Db_Table_Abstract
{
protected $_name = 'table_name';
private $_var;
public function __construct($var)
{
$this->_var = $var;
parent::__construct(); // add this
}
// the rest...
}
The parent constructor calls some protected methods _setup() (which in turn calls _setupDatabaseAdapter() and _setupTableName()) and init() (which is empty in the parent, but you can use to add some processing to the final step of object instantiation).
you have to be more clear when asking questions. write code if you have to.. No one can determine whats wrong with your application with only 2 piece of information.. with that said..
first yo should define your variable outside constructor and initialize inside the constructor if you have to.
Your model will not magically know that a db abstract class exist which connects to your database. you will have to create an object inside the model constructor.
here is the code
// DB Abstract class
class Application_Model_DbTable_myTable extends Zend_Db_Table_Abstract
{
protected $_name = 'myTable';
}
// Your model class
class Application_Model_myModel {
private $_var;
public function __construct() {
$this->_var = new Application_Model_DbTable_myTable();
}
}
Hope this was what you were looking for.. and only thing I understood from your question.
dins
It has been implied in other answers but not stated... You class failed because you overrode the constructor and didn't call the parent constructor so the object did not get created properly.
Normally when these classes are constructed, they are constructed through setOptions() which takes an array in constructor. So if you really have to override the constructor you might try something like:
public function __construct($var, $config = array())
{
$this->_var = $var;
parent::__construct($config);
}
now you should be able to set your variable and pass any configuration values you need to pass.
However it would be best to avoid the constructor and use the supplied init() method if at all possible.
<?php
class myClass extends Zend_Db_Table_Abstract
{
protected $_name = 'table_name';
private $_var;
public function init()
{
$this->_var = $var;
}
public function getById($id)
{
$select = $this->select()->where('id =?',$id);
return $this->fetchRow($select);
}
}
class a
{
public function __construct()
{
$this->id = 123;
}
}
class b extends a
{
public function __construct()
{
echo parent::id;
}
}
How do I pass variables that are set in the first class $this to the second class?
The correct way is to simply use $this->id in your subclass. All public/protected variables are available to subclasses this way. By assigning $this->id without declaring it, you've implicitly made it public. Generally you should explicitly declare the variable in the base class to document your intent to make it public:
class a
{
public $id;
public function __construct()
{
$this->id = 123;
}
}
Just remember to call parent::__construct() before you attempt to access members set by the parent class. Unlike some languages (C++) the parent class's constructor will not be automatically invoked for you.
class b extends a
{
public function __construct()
{
parent::__construct();
echo $this->id;
}
}
You can use parent::__construct() to get things that are initialized in the parent class. If you don't have anything to initialize in the child class you can avoid __construct() in the child class and it will automatically take the parent construct.
I want to do something like the following:
class SomeOtherClass {}
class Test
{
public $member = new SomeOtherClass();
}
The only problem is that I do not want to use a constructor, because the 'Test' class should extend another class and should not override the constructor.
Is this actually possible in PHP?
You can extend parent constructor in Test like this:
class Test extends SomeClass
{
public $member;
function __construct() {
$this->member = new SomeOtherClass();
parent::__construct();
}
}