服务容器/提供者的概念可能比我想象的要简单得多,但经过几个小时的阅读,我仍然完全不明白。
我在 app/Library 中创建了一个简单的 DateFormat 类。在 \config\app.php 中为其创建别名后,我可以立即在任何 Controller 或 Blade 模板中使用它。
<?php namespace App\Library;
class DateFormat {
public static function getDate($timestamp){
// processing the timestamp
}
}
我刚刚创建了一个服务容器吗?如果是,我还需要创建一个服务提供商吗?图片中的绑定(bind)在哪里?
我真的很感激能对这个主题有所了解。
谢谢
最佳答案
没有。您创建的只是您类(class)的别名。服务提供商是绑定(bind)特定类的一种方式,通常与 Facade 结合使用.
别名只是一种使用类的便捷方式,无需每次都导入整个命名空间类。
例如,如果您有一个类 \My\Very\Long\Class\Adapter,您可以在 config/app.php 中为其添加别名:
// config/app.php
<?php
'aliases' => [
// a bunch of aliases
'MyAdapter' => My\Very\Long\Class\Adapter::class,
]
现在你可以做:
<?php
new MyAdapter();
...
代替:
<?php
use My\Very\Long\Class\Adapter;
...
new Adapter();
...
当您想要解决依赖关系时,通常会使用服务提供者,最常见的是通过注入(inject)。当您要解析的类需要将参数传递给构造函数或每次都具有通用设置时,这会很有帮助。您可以在 Provider 中执行所有这些设置。
这是一个场景:
您有一个想要与之交互的 API。我们称之为 SuperApi。 SuperAPI 的文档说要创建 SuperApi 类的实例,您必须执行如下操作:
<?php
// Some method (a controller or something)
public function index()
{
$superApi = new \SuperApi\Connector($key, $secret);
return $superApi->getCustomers();
}
现在,每次你想创建它的实例时,你都必须做相同的设置(或将它抽象到某个类,但事实仍然是你需要传递一个 $key 和 $secret 给构造函数)。
如果您要为这个 Connector 类创建一个别名,可能是:
// config/app.php
<?php
'aliases' => [
// a bunch of aliases
'SuperApi' => SuperApi\Connector::class,
]
因此,使用该别名,您现在可以执行此操作:
<?php
// Some method (a controller or something)
public function index()
{
$superApi = new SuperApi($key, $secret);
return $superApi->getCustomers();
}
但是你看,即使有了别名,你仍然需要传递 $key 和 $secret。
这是服务提供商可以提供帮助的地方。
// app/Providers/SuperApiProvider.php
<?php
namespace App\Providers;
use SuperApi\Connector;
use Illuminate\Support\ServiceProvider;
class SuperApiProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
$this->app->bind('superApiConnector', function ($app) {
return new ApiConnector($app['config']->get('super-api.key'), $app['config']->get('super-api.secret'));
});
}
}
// app/Providers/SuperApi.php (the Facade)
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Facade;
class SuperApi extends Facade
{
protected static function getFacadeAccessor()
{
return 'superApiConnector';
}
}
// config/super-api.config
<?php
return [
'key' => env('SUPER_API_KEY'),
'secret' => env('SUPER_API_SECRET'),
];
// config/app.php
<?php
'providers' => [
// a bunch of providers
App\Providers\SuperApiProvider::class,
]
请注意,您在提供程序 ('superApiConnector') 中绑定(bind)的字符串与您从外观返回的字符串相同,外观的类名就是您实际调用绑定(bind)类,在本例中为 SuperApi。
现在,当你想使用 SuperApi\Connector 类时,你可以这样做:
<?php
// Some method (a controller or something)
public function index()
{
return SuperApi::getCustomers();
}
正如我上面所说,提供程序真正派上用场的地方是当你想注入(inject)它并拥有 Laravel's IoC Container 时。自动解析注入(inject)的类:
<?php
// Some method (a controller or something)
public function index(SuperApi $api)
{
return $api->getCustomers();
}
需要说明的是,您不需要服务提供商来利用依赖注入(inject)。只要类可以被应用程序解析,它就可以被注入(inject)。这意味着您要注入(inject)的类的构造函数采用的任何参数也需要是可自动解析的。
关于php - Laravel - 我的每个服务容器/自定义类都需要一个服务提供商吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46330374/
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除