11

Ive looked and tried but I can't find an answer.

In PHP, is it possible to call a class' member function (when that class requires a constructor to receive parameters) without instantiating it as an object?

A code example (which gives errors):

<?php

class Test {
    private $end="";

    function __construct($value) {
        $this->end=$value;
    }

    public function alert($value) {
        echo $value." ".$this->end;
    }
}

//this works:
$example=new Test("world");
$example->alert("hello");

//this does not work:
echo Test("world")::alert("hello");

?>
2
  • I thought echo Test::__construct("world")::alert("hello"); might work but it does not, sigh Commented Jun 23, 2010 at 4:07
  • 1
    making alert() to a static function will do the job. Commented Feb 25, 2014 at 10:10

6 Answers 6

30

Unfortunately PHP doesn't have support to do this, but you are a creative and look guy :D

You can use an "factory", sample:

<?php

class Foo
{
   private $__aaa = null;

   public function __construct($aaa)
   {
      $this->__aaa = $aaa;
   }

   public static function factory($aaa)
   {
      return new Foo($aaa);
   }

   public function doX()
   {
      return $this->__aaa * 2;
   }
}

Foo::factory(10)->doX();   // outputs 20
Sign up to request clarification or add additional context in comments.

2 Comments

I think won't work. As you cannot reference $this without making any object.
@SirajAlam it does make an object - look at the new Foo line...
13

Just do this (in PHP >= 5.4):

$t = (new Test("Hello"))->foo("world");

Comments

2

I, too, was looking for a one-liner to accomplish this as part of a single expression for converting dates from one format to another. I like doing this in a single line of code because it is a single logical operation. So, this is a little cryptic, but it lets you instantiate and use a date object within a single line:

$newDateString = ($d = new DateTime('2011-08-30') ? $d->format('F d, Y') : '');

Another way to one-line the conversion of date strings from one format to another is to use a helper function to manage the OO parts of the code:

function convertDate($oldDateString,$newDateFormatString) {
    $d = new DateTime($oldDateString);
    return $d->format($newDateFormatString);
}

$myNewDate = convertDate($myOldDate,'F d, Y');

I think the object oriented approach is cool and necessary, but it can sometimes be tedious, requiring too many steps to accomplish simple operations.

Comments

1

You can't call an instance-level method without an instance. Your syntax:

echo Test("world")::alert("hello");

doesn't make a lot of sense. Either you're creating an inline instance and discarding it immediately or the alert() method has no implicit this instance.

Assuming:

class Test {
  public function __construct($message) {
    $this->message = $message;
  }

  public function foo($message) {
    echo "$this->message $message";
  }
}

you can do:

$t = new Test("Hello");
$t->foo("world");

but PHP syntax doesn't allow:

new Test("Hello")->foo("world");

which would otherwise be the equivalent. There are a few examples of this in PHP (eg using array indexing on a function return). That's just the way it is.

1 Comment

i am creating an inline instance and discarding it immediately. i dont see why i need to allocate a variable to this process... is that just the way PHP/OOP is?
1
// this does not work:
echo Test("world")::alert("hello");

// works, as you are calling not to an object of the class, but to its namespace
echo Test::alert("hello");

Comments

1

For this you can do a

https://www.php.net/manual/en/reflectionclass.newinstancewithoutconstructor.php

reflect your class and trigger the new instance without constructor.

Here a sample code:

<?php

class Test {
    private $end="";

    function __construct($value) {
        $this->end=$value;
    }

    public function alert($value) {
        echo $value." ".$this->end;
    }

    public function end($value) {

        $this->end = $value;        

        return $this; // return Test object so that you can chain to other function method.
    }
}

// Solution #1:
// reflect your class.
$reflector = new \ReflectionClass('Test');

// Then create a new instance without Constructor.
// This will ignore the constructor BUT it will create a new instance of class Test.
$say = $reflector->newInstanceWithoutConstructor();

// use end method that will return the Test object, then you can chain the alert()
$say->end('World!')->alert("Hello"); // output: Hello World!

?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.