Access a class field from static method - php

For example, I have a class
class MyClass
{
public $something = 'base';
public function __construct()
{
$something = 'construct';
}
public function __destruct()
{
$something = 'destruct';
}
public static doSomething()
{
$return = new MyClass;
echo $return->something;
}
}
So, my question is this... Will running the static method without instantiating the object run the constructor? If I had, for example, database connection information in the constructor, could I run a static method that returns a query withing explicitly instantiating the class?
Thanks in advance

Yes the construction will be called in your example. Since you already have the code, I guess it would be easy to test.

If you execute MyClass::doSomething(), it will create object of MyClass and, of course, its constructor will be called. Why not to run it and see the result?

I'm lacking PHP knowledge, but compared to other OO languages it will of course run the constructor, because you tell the static method to create a new instance of MyClass.
The same would apply if you called a new SomeOtherType. The code itself doesn't care if it's inside a static/public/private method, as long as new is there, the constructor is invoked.

I did not ask the question correctly, but the answer is that as long as the object is instantiated, even within a static method, the constructor will run. The output would be whatever is in the constructor as the deconstructor does not fire until after the last call to the class.
Sorry for the confusion in the question.

Related

Calling a static parent method while instantiating child class

I'm changing my class structure around to store common database methods in one class. Then extending it from a child class. This should cut down on code but also allows me to overwrite the parent methods when I need to.
I've done the following, for this example I've simplified to the basics compared to the original code which contains more classes.
class parent_object{
private $table_name;
public function all_records(){
$sql = "SELECT * FROM ".$this->table_name;
return $this->execute_sql($sql);
}
}
class child_object extends parent_object{
protected static $table_name="tbl_name";
public function __construct(){
parent::__construct(self::$table_name);
}
}
I want to call the all_records() statically to save myself creating a new object every time.
I'm stuck having to instantiate the child and then call the parent method
$child = new child_object();
$all = $child->all_records();
What I really want to be able to call the parent method statically:
$all = child_object::all_records();
I understand why I can't do it with my code, but would like some way that the child instantiates first then accesses the parent method.
I could write all_records() method in the child_object to instantiate itself and call the parent all_records() but that sort defeats the purpose of extending to cut down on code and the same methods in my child class.
I'm sure its quite simple or some new high level oop function can do it.
Thanks for your help.
The answer is relatively simple, you can turn all your properties into static properties, and then use static:: instead of self::.
http://php.net/manual/en/language.oop5.late-static-bindings.php
Solving your problem this way is considered a bad practice though. Good luck.
You could do something like this:
class child_object extends parent_object
{
protected static $table_name="tbl_name";
public static function factory()
{
return new child_object();
}
public function __construct()
{
parent::__construct(self::$table_name);
}
}
Then when you use it you just do:
$all = child_object::factory()->all_records();

PHP Call Function in a Class - Is there a simpler way?

I am very new to OOP and very rusty on PHP. I was wondering if this is a valid method to call a function from a class?
class newclass {
public function testfunc {
return '1';
}
}
Could I call it like this:
echo testfunc->newclass();
or like this:
echo newclass()::testfunc;
I always see it defined in examples like below and it seemed like extra code?:
$this = new newclass();
$this->testfunc();
echo $this;
Any help would be greatly appreciated as I'm just starting to wrap my head around this OOP thing. If I'm out to lunch maybe someone could suggest a link to a really good guide for a true beginner in classes/OOP. Thanks!
Both ways work and have their use cases.
Your first case is a regular function call using an instance of a class, your second case is a call to a static function.
Static should be used with care and the use of it is very often a sign that refactoring/redesign is necessary.
The point of object oriented programming is to model the world by writing classes (blueprints) and then create as many independent instances of that class with the word new as needed. Each instance is a little organism with the DNA of the class and you can call the same class method on every single instance without influencing the other instances.
A static call however is not related to an instance of a class and therefore there is no object being used. It's a global call of some tool functionality and in fact breaks the idea of encapsulation.
So, I'm not saying there are no use cases for static classes and methods but they should be used with care.
new is the keyword to instantiate the class. If you want to use a method without an instance of the class, it should be a static method. to have a static method, declare the method as static.
class foo
{
public static function bar()
{
return 'hello!';
}
}
How to use it?
echo foo::bar(); //Will print hello
You could make testfunc static and call it like so:
class newclass{
public static function testfunc{
return '1';
}
}
echo newclass::testfunc();
There is nothing like this echo testfunc->newclass(); and doing it like
$class = new newclass();
echo $class->testfunc();
is the proper way to do it when the method is an instance method and not a static one. Note, there is no ability to reference $this within the static method.
You can create a static wrapper for the constructor which would allow for chaining method calls on the same line.
<?php
class ClassA {
static function create() { return new self(); }
function method1() { ... }
}
ClassA::create()->method1();
you can include the php file that contains your functions
<?php
//print.php
function printHello(){
echo "Hello world";
}
?>
then include it and call the function...
<?php
include "print.php";
printHello();
?>

purpose of constructor in php [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Benefits of using a constructor?
hello coders. I am newbie to OOP in php. I am doing a project in objects and class. where
most of time I face a line
public function __construct(){
}
I can't understand this. Why its used and what is its value. Can some one tell me about it. I went to the php.net site but my doubt not cleared.
when using oop, a constructor gives basic initialization details for an object.
See:
http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)#PHP
The __construct allows arguments to be passed to an object on initalisation, without you would do something like this:
$myobj = new Object();
$myobj->setName('Barry');
But if you have this:
public function __construct($name='')
{
$this->name = $name;
}
You can just do:
$myobj = new Object('Barry');
Another possible use for the constructor (though not good practice):
public function __construct()
{
ob_start(); //Some random code that you may want to run as soon as object is initialised
}
It's a method within a class. When you construct an object from a class, this associated constructor is called. It has the "__" magic method prefix.
This method is automatically called when a class is instantiated.
There is also a __destruct() method, which as you might guess is automatically called when a class is destroyed.
Have a read here:
http://php.net/manual/en/language.oop5.decon.php
The value of the __construct is to initialize any newly created object in a method that's native to OO design.
So, rather than doing something like this:
$o = new MyObject();
$o->Initialize();
We can simply do this:
$o = new MyObject();
And within the MyObject class:
class MyObject
{
public function __contruct()
{
// initialization code here
}
}

Can you explain how Zend's Action controller operating?

Sorry for constantly re-editing my question but looks like this is the only way to ask it properly.
My original problem is the following pseudo-code (a controller and it's parent) isn't working as i would like to:
class Parent {
var $data = array();
public function __construct( OtherClass $otherClass ) {
$this->data = $otherClass->getData(); //contains some => thing
$this->init($otherClass->getClassName());
}
public function init( $className ) {
new $className; //new Child
}
public function __get( $name ) {
return array_key_exists($name, $this->data) ? $this->data[$name] : null;
}
}
class Child extends Parent {
public function __construct() {
echo $this->some; //won't return 'thing';
}
}
fireeyedboy helped me a lot (thank you) and pointed out Zend_Controller_Action is doing what i want but i can't understand how they do it?
Original question
I know there was some similar questions here but i cannot dump them. Also i know i can reverse the whole process so i can initialize Child first then call parent::__construct but this seems unwanted for me. How can i access Parent variables easily in my case?
Update:
Let me clarify a little bit. Child is an arbitrary controller. Parent is the mother of all controllers. Many frameworks are doing the same but controllers can utilize their parent controllers variables, methods or objects without calling parent::__construct (and therefore filling child class constructors with unnecessary arguments). I don't like to rewrite any of these frameworks but i'd like to understand how they're operating.
Your child class doesn't call parent constructor. Here's a fix:
class Child extends Parent {
public function __construct() {
parent::__construct();
echo $this->some;
}
}
Update: Parent classes' constructors aren't called automatically in PHP. See the documentation:
Note: Parent constructors are not
called implicitly if the child class
defines a constructor. In order to run
a parent constructor, a call to
parent::__construct() within the child
constructor is required.
So what you're asking does not happen. Either you have misinterpreted the class structure or how they operate. Note that PHP also supports legacy constructor naming (at least until 5.3.3): If there is no __construct() method in a class, PHP assumes the constructor is named after the class (ie. class Foo { function Foo() {}) treats the Foo() method as constructor).
Injecting ANYTHING using controller's construct is generally a BAD PRACTICE! Problem lies in your design. What kind of object is OtherClass? Is it DB adapter? Is it ACL? Is it some helper class?
If you need external class in your controller I suggest using action helpers. That's what they are created for ;) Or create an action helper that will fetch this OtherClass from somewhere when needed.
You should NEVER use __construct() to do any of your dirty work. That's what init() is used for. But it has no params. And there is a reason for that - again - you should not inject dependencies like this ;)
Update:
Note your class uses discouraged PHP4 member variable definition syntax. Try replacing your var with protected.
The problem is that your Child class does not call the base constructor.
Incidentally, Parent is not a valid class name in PHP. I have changed the class names for clarity. See below:
class ChildClass extends ParentClass {
public function __construct() {
parent::__construct(/* what goes here? */);
echo $this->some;
}
}
However, note the what goes here? part: your base class requires a reference to an OtherClass instance to be constructed. Therefore, since ChildClass IS-A ParentClass, it also needs to get such an instance somehow. You will need to either add a parameter to ChildClass::__construct and forward the value to parent::__construct, or somehow figure out a default value yourself.

Use an instance of an object throughout the site with PHP

How will I use an instance of an object that is initially loaded throughout the whole site?
I want $myinstance to be used everywhere.
$myinstance = new TestClass();
Thanks!
What you are looking for is called the singleton pattern.
If you are deeply into OOP architecture, and want to do things like Unit Testing in the future: Singletons are regarded as an imperfect approach and not "pure" in the sense of OOP. I asked a question on the issue once, and got pretty good results with other, better patterns. A lot of good reading.
If you just want to get started with something, and need your DB class available everywhere, just use a Singleton.
You just need to declare your variable in global scope (for example, in the begginning of your whole code), and when you want to use it inside a function, use the "global" statement. See http://php.net/global.
I'm not 100% sure I got what you want to do... but I'll try to answer anyway.
I think you can save it to a session variable, using the serialize/unserialize functions to save/retrieve your class instance. Probably you'd code TestClass as a singleton, but that really depends on what you're trying to do.
For instance:
if (!isset($_SESSION["my_class_session_var"])) // The user is visiting for the 1st time
{
$test = new TestClass();
// Do whatever you need to initialise $test...
$_SESSION["my_class_session_var"] = serialize($test);
}
else // Session variable already set. Retrieve it
{
$test = unserialize($_SESSION['my_class_session_var']);
}
There is a design pattern called Singleton. In short:
Change __construct and __clone to private, so calling new TestClass() will end up with Error!
Now make a class that will create new instance of your object or return existing one...
Example:
abstract class Singleton
{
final private function __construct()
{
if(isset(static::$instance)) {
throw new Exception(get_called_class()." already exists.");
}
}
final private function __clone()
{
throw new Exception(get_called_class()." cannot be cloned.");
}
final public static function instance()
{
return isset(static::$instance) ? static::$instance : static::$instance = new static;
}
}
Then try to extend this class and define static $instance variable
class TestClass extends Singleton
{
static protected $instance;
// ...
}
Now try this:
echo get_class($myinstance = TestClass::instance();
echo get_class($mysecondinstance = TestClass::instance());
Done

Categories