2014-12-12 6 views
0

Я вызываю класс по строковой переменной, переданной аргументом функции.Вызов класса по строке PHP

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 Модель

namespace MyApp\Sites; 

class Site extends \Eloquent { 

} 

Но если я вызываю класс, который содержит, например, строковая переменная $type; string variable $type содержит «Сайт», он говорит, что класс «Сайт» не найден.

Я попытался вручную набрать Site::create($stub) и, наконец, принимает его.

Я также попытался call_user_func($type::create(), $stub); и $model = new $type; $model->create($stub); , но, к сожалению, это говорит класс «Сайт» не найден.

Любые идеи?

+1

Возможно, потому, что у вас есть только класс 'SiteTester', или вы не показываете какой-либо свой код? – Justinas

+0

Что ты имеешь в виду? @Justinas? –

+0

'class SitesTester расширяет ApiTester()' – Justinas

ответ

0

Вы почти там:

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

$cls = 'X'; 

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

Если ваш PHP очень старый (< 5,3 я считаю), вы должны использовать массив вместо:

print call_user_func(array($cls, "foo"), 'there'); 
+0

OP также ищет параметры, поэтому вы можете изменить этот ответ на 'call_user_func_array'. Версия PHP-версии сейчас не актуальна, потому что она относится только к ключевым словам класса, таким как «parent» и «self» и т. Д. – Eduard

+0

@edduvs: хороший вызов, добавленный аргумент к примеру. – georg

+0

@georg: Я попробовал 'call_user_func (" $ type :: create ", $ stub);' но он говорит 'call_user_func()' ожидает, что параметр 1 будет действительным обратным вызовом –

0

Вы можете заменить что static class call со следующим:

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

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

Runnable код здесь: http://runnable.com/VIqy4CDePeY-AeMV/output

+0

Я думаю, что laravel выглядит красноречивыми моделями в папке приложений \ моделей, хотя мне уже требуются красноречивые классы в классе ApiTester. Таким образом, я перемещаю файл Site.php в каталог app \ models из каталога MyApp \ Sites. И я просто использую '$ type :: create ($ stub);' и это сработало. Поэтому я думаю, что проблема в том, что вы вызываете класс eloquent через строковую переменную, он смотрит на каталог app \ models. –

Смежные вопросы