I have an idea of using this syntax in php. It illustrates that there are different fallback ways to create an object
function __construct() {
if(some_case())
$this = method1();
else
$this = method2();
}
Is this a nightmare? Or it works?
Or it works?
It doesn't work. You can't unset or fundamentally alter the object that is being created in the constructor. You can also not set a return value. All you can do is set the object's properties.
One way to get around this is having a separate "factory" class or function, that checks the condition and returns a new instance of the correct object like so:
function factory() {
if(some_case())
return new class1();
else
return new class2();
}
See also:
Breaking the constructor
PHP constructor to return a NULL
Why not to do something more common like:
function __construct() {
if(some_case())
$this->construct1();
else
$this->construct2();
}
You can just create class methods method1 and method2 and just write
function __construct() {
if(some_case())
$this->method1();
else
$this->method2();
}
You can make factory method.
Example:
class A {}
class B {}
class C {
function static getObject() {
if(some_case())
return new A();
else
return new B();
}
}
$ob = C::getObject();
It sounds a little bit like the Singleton class pattern.
See #Ivan's reply among others for the correct syntax for what it looks like you're trying to do.
However, there are is another alternative - use a static method as an alternative constructor:
class myclass {
function __construct() { /* normal setup stuff here */}
public static function AlternativeConstructor() {
$obj = new myclass; //this will run the normal __construct() code
$obj->somevar = 54; //special case in this constructor.
return $obj;
}
}
...
//this is how you would use the alternative constructor.
$myobject = myclass::AlternativeConstructor();
(note: you definitely can't use $this in a static method)
If you want to share some functions, do some like
class base{
'your class'
}
class A extends base{
'your class'
}
class B extends base{
'your class'
}
And call like
if(some_case())
$obj = new A();
else
$obj = new B();
Related
I am new to php and trying to call a function in another class.
How do I call function1 and function2 in class xyz???
class abc {
private $lmn = "lmn";
private $say1;
private static $static;
private function __construct(){
$say1 = print $this->lmn;
}
public static function1(){
$static = "YEAAHHHH";
}
public function function2(){
return $this->say1;
}
file 2:
require 'abc.php';
class xyz {
/**
* $e = new xyz();
*
*/
$e = xyz:: function1();// error
$d = xyz:: function 2(); //error
}
Also under what circumstance I should use
$obj = new class();
$obj->functionname();
and
$obj = class::functionname();
You have 2 different types of methods here, static and non-static.
To call the static (function1())
You don't need to instantiate the class, as it's static.
class zyx {
public function foo() {
return abc::function1();
}
}
To call the non-static (function2())
You need to instantiate the class, as it's not static.
class zyx {
public function foo() {
$abc = new abc();
return $abc->function2();
}
}
You would call function1 like:
abc::function1();
It is a method in abc not xyz.
function2() you would only call if you had an instance of abc because it is an instance method and not a static method. I.e.
$abc = new abc();
$abc->function2();
Static functions are intended to be called on classes, instance methods (i.e. function2() are intended to be called on instances of classes. I would recommend reading http://php.net/manual/en/oop5.intro.php.
Static functions can be called without instantiating your class...
$myClass::function1();
Non-static functions need to be instantiated first:
$myClass = new abc();
$myClass->function2();
So in your example:
require 'abc.php';
class xyz {
public function CallFunc1()
{
abc::function1();
}
public function CallFunc2()
{
$myClass = new abc();
$myClass->function2();
}
}
require 'abc.php';
class xyz {
public function static(){
return abc:: function1();// this is a static function
}
public function nonstatic(){
$e = new abc();
return $e->function2();
}
}
First of all, you can't have a space between function and 2():
$d = xyz::function2(); //correct
$d = xyz::function 2(); //very incorrect
I was going to have a second of all, but #hd beat me to it.
I think you have messed up with the code. I can share something with something that I found very helpful as an answer for your second question. Spend a bit time reading this. This is very basic, simple and well guided.
http://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762
I'm new to programming. I have this going on:
I have Class A, which have many functions. One of those functions is functionX.
In functionX I need to make a call to functionY which belongs to another class: Class B.
So how do I acces to functionY from inside functionX?
I use Codeigniter.
Thanks in advance.
Try and experiment with this.
class ClassA {
public function functionX() {
$classB = new ClassB();
echo $classB->functionY();
}
}
class ClassB {
public function functionY() {
return "Stahp, no more OO, stahp!";
}
}
Class function? A static method?
If you have an instance (public) method, you just call $classB->functionY().
If you have a static method, you would call ClassB::functionY();
So:
class ClassA {
public function functionX(){
$classB = new ClassB();
// echo 'foo';
echo $classB->functionY();
// echo 'bar';
echo ClassB::functionYStatic();
}
}
class ClassB {
public $someVar;
public static $someVar2 = 'bar';
function __construct(){
$this->someVar = 'foo';
}
public function functionY(){
return $this->someVar;
}
public static function functionYStatic(){
return self::$someVar2;
}
}
Well that depends. If that function is a static function or not.
First off you must include the file with the class...
include_once('file_with_myclass.php');
If it is static you can call it like this:
ClassName::myFunction()
If it is not, then you create an instance of the class and then call the function on that instance.
$obj = new ClassName();
$obj->myFunction();
As you can guess the function being static means you can call it without the need of creating an instance. That is useful for example if you have a class Math and want to define a function that takes to arguments to calculate the sum of them. It wouldn't really be useful to create an instance of Math to do that, so you can declare as static and use it that way.
Here's a link to the docs with further info
http://www.php.net/manual/en/keyword.class.php
If functionY is static you can call ClassB::functionY(). Else you must create instance of Class B first. Like:
$instance = ClassB;
$instance->functionY();
But maybe you mean something else?
Looks like one of your class has a dependency to another one:
<?php
class A
{
public function x()
{
echo 'hello world';
}
}
class B
{
private $a;
public function __construct(A $a)
{
$this->a = $a;
}
public function y()
{
$this->a->x();
}
}
$a = new A();
$b = new B($a);
$b->y();
Depending how your code looks like, if it makes sense, you can inject class A into y()
public function y(A $a)
{
// your code with $a
}
I want to know if I can somehow assign new variable without making constructor.
It seems pretty big overkill to create constructors on every class just to set initial private class variables.
Here is my example of what I want to achieve
<?php
class MyClass {
public function DoSomething() {
echo '1';
}
}
class MySecondClass {
private $obj = new MyClass(); // Error
/*
// This works, but I don't like it, I think it's total overkill
function __construct() {
$this->obj = new MyClass();
}
*/
public function PrintOne() {
$this->obj->DoSomething();
}
}
$class = new MySecondClass();
$class->PrintOne();
Just so it's perfectly clear here's the error message
syntax error, unexpected 'new' (T_NEW) on line 10
You can't (that I know of), you need to either instantiate it in the constructor (Option A), or pass in the object (Option B).
Option A:
class MySecondClass {
private $obj;
function __construct() {
$this->obj = new MyClass();
}
public function PrintOne() {
$this->obj->DoSomething();
}
}
Option B:
class MySecondClass {
private $obj;
function __construct(MyClass $obj) {
$this->obj = $obj;
}
public function PrintOne() {
$this->obj->DoSomething();
}
}
You can't do that in that manner. You can have properties be initialized but they need to be a constant value and not the result of a function or trying to instantiate a class.
http://www.php.net/manual/en/language.oop5.properties.php
IMO, You shouldn't instantiate new objects within the constructor of your classes. You should pass them in as arguments for creating the object.
We have the following chaining:
$obj = new obj();
$obj->setname($params1)->setcolor($params2);
Is there a way to do the same chaining on one line, without creating a dummy function?
P.S: I want to skip the part where the constructor itself is on a new line. I want to construct the object and start the chaining on the same line. Something like this:
$obj = new obj()->setname($params1)->setcolor($params2);
Since PHP 5.4, class member access on instantiation has been added so you can do it like this:
$obj = (new obj())->setname($params1)->setcolor($params2);
In previous versions, like you I hate that you have to instantiate the object on one line and then start using it on another, so I have a global function _i() which looks like this:
function _i($i) { return $i; }
I use it like this:
_i(new Obj)->doThis($param)->doThat($param2);
Some people will find it ugly but PHP lacks language expression power, so it works for me :)
I use static functions of class for it.
class a{
static public function gets($args){
return new self($args);
}
public function do_other(){
}
}
a::gets()->do_other();
Usually there are more then I static method to different usages
Should be possible if you allways return the object itself in the function.
function setname($param) {
// set the name etc..
return $this;
}
You can also use PHP type hinting to make sure only the correct object is used as an argument
function instance(sdtClass $instance) { return $instance }
or as the static method using the class name
class CustomClass{
static public function gets(CustomClass $obj){
return $obj;
}
}
You can also use this technique from Singleton pattern (without using singleton pattern):
<?php
class test
{
public function __construct() {
}
public static function getInstance() {
return new test();
}
public function chain() {
echo 'ok';
}
}
// outputs 'ok'
$test = test::getInstance()->chain();
Sure is. Simplt return this at the end of each function, to return the object so your next chained function can use it.
<?php
class A
{
public __constructor()
{ .... }
public function B($params)
{
//Processing
return this;
}
public function C($params)
{
//Processing
return this;
}
public function D($params)
{
//Processing
}
}
$O = new A();
$O->B($params)->C($params)->D($params); //Will work because B and C return this
$O->B($params)->D($params)->C($params); //WILL NOT work because D doesn't return this
?>
class foo(){
function bar()
{
$classInstance = $this->createClassInstance($params);
$result = $classInstance->getSomething();
}
function createClassInstance($params)
{
require 'path/to/class.php';
$myClass = new Class;
$myClass->acceptParams($params['1']);
$myClass->acceptMoreParams($params['2']);
.... lots more params
return $myClass;
}
}
Can I initiate a new class by calling a method that returns a class object? The class in question has lots of parameters and I need to call it multiple times within bar() so I thought it would be neater to do it that way, but I can't get it working and want to check if it's possible + good practice?
That's called factory class (Factory OO Design Pattern).
How it should be done in PHP: http://www.php.net/manual/en/language.oop5.patterns.php
What I think you're describing is the Factory pattern, but you're using parameters to set the class variables just like you would in a constructor, so why not just use that?
Edit:
Ah, if you're using the same parameters for the most part then you definitely want the Factory pattern. Just use a static function to return an instance of the class, and put it inside the type of class you're returning:
class MyClass
{
public static function factory($params)
{
$myClass = new MyClass;
$myClass->acceptParams($params['1']);
$myClass->acceptMoreParams($params['2']);
//.... lots more params
return $myClass;
}
}
class foo(){
function bar()
{
$classInstance = MyClass::factory(param1, param2);
}
}