我正在开发一个ZF2系统并且它运行良好,但在我在其他计算机中克隆存储库之后,这个已弃用的错误已经出现:
您正在从Module \ Controller \ Controller类中检索服务定位器。请注意,ServiceLocatorAwareInterface已弃用,将在3.0版中与ServiceLocatorAwareInitializer一起删除。您需要更新您的类以在创建时接受所有依赖项,通过构造函数参数或setter,并使用工厂执行注入。在第258行的/home/path/project/vendor/zendframework/zend-mvc/src/Controller/AbstractController.php
composer.json:
public class ServerFragment extends Fragment {
TextView urlTextView, nodeTextView, valueTextView;
public static String passValue;
//Graph
GraphView graphView;
public LineGraphSeries<DataPoint>mySeries;
private double graph2LastXValue = 5d;
public View myFragmentView;
public String url, namespace, nodeName;
public ServerFragment() {}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myFragmentView = inflater.inflate(R.layout.fragment_server, container, false);
urlTextView = (TextView)myFragmentView.findViewById(R.id.urlTextView);
nodeTextView = (TextView)myFragmentView.findViewById(R.id.nodeTextView);
valueTextView = (TextView)myFragmentView.findViewById(R.id.valueTextView);
//Graph
graphView = (GraphView)myFragmentView.findViewById(R.id.graphView);
mySeries = new LineGraphSeries<DataPoint>();
mySeries.setColor(Color.RED);
graphView.addSeries(mySeries);
graphView.getViewport().setXAxisBoundsManual(true);
graphView.getViewport().setMinX(0);
graphView.getViewport().setMaxX(100);
graphView.getViewport().setMinY(-20);
graphView.getViewport().setMaxY(70);
url = getArguments().getString("url");
urlTextView.setText(getArguments().getString("url"));
nodeTextView.setText(getArguments().getString("ns") + " | " + getArguments().getString("nodeName"));
return myFragmentView;
}
public void setData() {
Bundle bundle = this.getArguments();
String value = bundle.getString("value");
graph2LastXValue += 1d;
try {
mySeries.appendData(new DataPoint(graph2LastXValue, Double.parseDouble(value)),
true, 200);
}
catch (Exception e)
{
Log.d("mySeries.appendData", e.getMessage());
}
try {
valueTextView.setText(value);
}
catch (Exception e)
{
Log.d("valueTextView", e.getMessage());
}
Log.d("Serverfragment setData:" , value);
}
@Override
public void onStart() {
super.onStart();
setData();
}
@Override
public void onDestroy() {
Log.d("ServerFragment", "disconnected");
super.onDestroy();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static ServerFragment newInstance(String url, String ns, String nodeName) {
ServerFragment sf = new ServerFragment();
Bundle b = new Bundle();
b.putString("url", url);
b.putString("ns", ns);
b.putString("nodeName", nodeName);
sf.setArguments(b);
return sf;
}
}
我在控制器中检索服务时出现错误(扩展Zend \ Mvc \ Controller \ AbstractActionController):
"require": {
"php": ">=5.5",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"zendframework/zendframework": "~2.5",
"doctrine/doctrine-orm-module": "0.*",
"hounddog/doctrine-data-fixture-module": "0.0.*",
"imagine/Imagine": "~0.5.0"
在Zend \ Mvc \ Controller \ AbstractController的Zend核心中是这样的:
$this->getServiceLocator()->get("Module\Service\Service");
之前只有这个:
public function getServiceLocator()
{
trigger_error(sprintf(
'You are retrieving the service locator from within the class %s. Please be aware that '
. 'ServiceLocatorAwareInterface is deprecated and will be removed in version 3.0, along '
. 'with the ServiceLocatorAwareInitializer. You will need to update your class to accept '
. 'all dependencies at creation, either via constructor arguments or setters, and use '
. 'a factory to perform the injections.',
get_class($this)
), E_USER_DEPRECATED);
return $this->serviceLocator;
}
我已经尝试了一切,有人知道我该做什么吗?
答案 0 :(得分:10)
您无需执行任何操作,尚未。升级到ZF3时,您必须更改控制器类接收其依赖项的方式。
ZF2支持两种依赖注入模式:服务定位器和构造函数。 ZF3删除“按服务位置”并且需要“通过构造函数”。实际上,这一切确实改变了依赖关系如何解决,将解决方案从“及时”转移到“建设中”。
而不是从任何地方获取服务,而是在构建接收它们。按以下方式更新您的代码:
namespace Module\Controller;
class Controller {
public function __construct(\Module\Service\Service $service) {
$this->service = $service;
}
}
在课程方法中使用$this->service
所需的位置。
然后使用控制器工厂来创建控制器,如下所示:
function ($controllers) {
$services = $controllers->getServiceLocator();
return new \Module\Controller\Controller($services->get('Module\Service\Service'));
}
Issue 5168中讨论了此更改,this blog post讨论了服务注册服务注入为反模式的原因。
答案 1 :(得分:1)
你可以创建一个控制器插件 service()(但这是一个不好的做法,更喜欢FactoryInterface)
<强> module.config.php 强>
'controller_plugins' => [
'factories' => [
'service' => YourNamespace\Mvc\Controller\Plugin\Service\ServiceFactory::class,
],
],
<强> YourNamespace \的mvc \控制器\插件\服务\ ServiceFactory.php 强>
<?php
namespace YourNamespace\Mvc\Controller\Plugin\Service;
use Interop\Container\ContainerInterface;
use YourNamespace\Mvc\Controller\Plugin\Service;
use Zend\ServiceManager\Factory\FactoryInterface;
class ServiceFactory implements FactoryInterface
{
/**
* @param ContainerInterface $container
* @param string $requestedName
* @param array $options
* @return Service
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$plugin = new Service();
$plugin->setServiceLocator($container);
return $plugin;
}
}
<强> YourNamespace \的mvc \控制器\插件\ Service.php 强>
<?php
namespace YourNamespace\Mvc\Controller\Plugin;
use Interop\Container\ContainerInterface;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
/**
* Plugin: $this->service();
*/
class Service extends AbstractPlugin
{
/**
* @var ContainerInterface
*/
protected $serviceLocator;
/**
* @return ContainerInterface
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
/**
* @param ContainerInterface $serviceLocator
* @return Service
*/
public function setServiceLocator(ContainerInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
/**
* @param string $name
* @return object|bool
*/
public function __invoke($name = null)
{
$sl = $this->getServiceLocator();
if (!$name) {
return $sl;
}
if (!$sl->has($name)) {
return false;
}
return $sl->get($name);
}
}