0

I'm calling a class by a string variable passed on a function argument.

ApiTester.php

   use MyApp\Sites\Site;

   abstract class ApiTester extends TestCase() {

   /**
     * Make a new record in the DB
     * 
     * @param $type
     * @param array $fields
     * @throws BadMethodCallException
     */
    protected function make($type, array $fields = [])
    {
        while($this->times--)
        {
            $stub = array_merge($this->getStub(), $fields);

            $type::create($stub);
        }


    }

SitesTester.php

class SitesTester extends ApiTester() {

/** @test */
public function it_fetches_a_single_site()
{
    // arrange
    $this->make('Site');

    // act
    $site = $this->getJson('api/v1/sites/1')->data;

    // assertion
    $this->assertResponseOk();

    $this->assertObjectHasAttributes($site, 'name', 'address');
}

Site.php // Eloquent Model

namespace MyApp\Sites;

class Site extends \Eloquent {

}

But if I call the class that the string variable $type contains, for example; string variable $type contains 'Site', it says class 'Site' not found.

I tried to manually type Site::create($stub) and finally accepts it.

I also tried call_user_func($type::create(), $stub); and $model = new $type; $model->create($stub); but unfortunately it says class 'Site' not found.

Any ideas?

6
  • 1
    Maybe because you only have class SiteTester or are you not showing some code of yours? Commented Dec 12, 2014 at 8:44
  • what do you mean? @Justinas? Commented Dec 12, 2014 at 8:51
  • class SitesTester extends ApiTester() Commented Dec 12, 2014 at 8:59
  • What Justinas has pointed out is you are using the literal name of 'Site'. We do not see anything to do with that name in your code. We can see SitesTester.. but not Site. Commented Dec 12, 2014 at 9:04
  • @Justinas, what should it be? Commented Dec 12, 2014 at 9:05

2 Answers 2

0

You're almost there:

class X {
    static function foo($arg) {
        return 'hi ' . $arg;
    }
};

$cls = 'X';

print call_user_func("$cls::foo", 'there');

If your php is very old (<5.3 I believe), you have to use an array instead:

print call_user_func(array($cls, "foo"), 'there');
Sign up to request clarification or add additional context in comments.

2 Comments

OP is looking for params too, so you migh be changing that answer to call_user_func_array. The PHP version thing is not relevant now because it's only related to class keywords like parent and self etc.
@georg: I tried call_user_func("$type::create", $stub); but it says call_user_func() expects parameter 1 to be a valid callback
0

You may want to replace that static class call with the following :

        while( $this->times-- )
        {
            $stub = array_merge( $this->getStub(), $fields );

            call_user_func( "$type::create",  $stub );
        }

Runnable code here : http://runnable.com/VIqy4CDePeY-AeMV/output

1 Comment

I think laravel is looking eloquent models in app\models folder even though I already require the eloquent classes at the ApiTester class. So, I move my Site.php file into app\models directory from MyApp\Sites directory. And I just use the $type::create($stub); and it worked. So I think the problem is if you call a eloquent class via string variable, it looks at the app\models directory.

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.