我正在构建一个解析器系统,它将根据请求/cronjob解析不同XML/JSON提要的负载。我用的是拉拉维尔4号。
线程的目的是在我的上下文中使用IoC,而不是在自定义类方法中硬编码模型名称
为足球运动员提供XML结构的解析器示例,如下所示:
<players category="Midfielders">
<player id="777">
<name>Caio Augusto Paim do Santos</name>
<statistic>
<club name="Camaçari" id="7191" league="Baiano 2" league_id="1136" season="2013" minutes="" appearences="" lineups="" substitute_in="" substitute_out="" substitutes_on_bench="" goals="" yellowcards="" yellowred="" redcards=""/>我在我的/app文件夹中创建了一个名为/parsers的附加目录--它们都是自定义类,它们都在同一个文件夹中扩展或实现自定义抽象/接口,基本上负责接收到XML/JSON文件的路径并返回结构良好的PHP数组。
它们是在composer.json中自动添加的,as:"app/parsers"
附呈的文件结构截图

一切都很好,代码/类是可测试的,不依赖于其他类,但问题是这样的。
请查看XML示例,比如:<club id="XXX" league_id="YYY" /> --这是提要俱乐部id和提要联盟id,但我在数据库中有引用提要id的id。
就像这张截图:

因此,逻辑是:转到数据库,检查是否有从XML文件中提供的feed_id列表中的id。如果是,得到它,如果不是,创建一个新的联盟,并得到id为未来的参考。
这要求我在解析器类中使用模型,现在我知道您可以使用IoC并将模型注入控制器,但我不确定我的解析器类是否也能这样做.
因此,在解析器类的中间执行这样的操作:
// Try to get league and season ids from database if they already exists, if not, insert
$leagueId = DB::select('SELECT id FROM league WHERE feed_id=?', array($data['league_id']));或
$league = new LeagueModel();基本上是错误的。
现在,为了澄清这一切的工作方式,我的解析器在类中被调用如下:
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->setParser();
$this->setStorage();
$this->parser->parseFile($file);
}而Laravel命令类在我的控制器中被调用,比如:
$stamps = $this->getStamp();
Artisan::call('command:getSoccerPlayer',array('stamps' => $stamps, 'parser_id' => Request::segment(2)));控制器本身通过URI:/jobs/soccer_player/parse?type=soccer&directory=players调用
**您有什么建议,或者您将如何克服这个问题,以避免依赖关系,并在这种情况下仍然使用模型与数据库进行交互?
请不要注意,我的屏幕截图上的整个解析逻辑都在同一个方法“解析”中,现在,一旦我看到了我希望它如何工作/看上去的全貌,我就会把它分解成几个部分。
感谢你的帮助!
发布于 2014-01-09 17:35:54
您仍然可以调用您的命名空间模型。
use App\Models\League;
class SoccerPlayerParser extends AbstractParser{
//...
public function parse()
{
//...
$league = App\Models\League::find($data['league_id']);
//...
}
//....
}发布于 2014-01-17 18:28:54
我在这里看到了两个可能的解决方案,但我不能百分之百地确定如何将它集成到您的项目中。
第一种方法是存储要在配置文件中使用的模型类的名称,并通过new $class对模型进行定位,其中$class是通过Config::get或类似的方法检索的值。这种解决方案在包中非常常见,甚至Laravel本身也使用它(请参阅app/config/auth.php中的模型设置)。
另一种是不实例化模型,而是为它创建一个接口,然后依赖--将它注入您的命令中。通过使用Artisan::resolve('MyNamespace\MyCommand')而不是Artisan::add(new MyCommand),您可以轻松地将内容自动注入到命令中,然后像通过控制器那样通过类型提示进行注入。http://laravel.com/docs/ioc#practical-usage
一旦将接口设置为命令的构造函数的参数,就可以使用App::bind('MyInterface', 'MyModel')来告诉Laravel要注入哪个类,这可以在任何时候交换。
https://stackoverflow.com/questions/21026782
复制相似问题