不推荐使用:在功能系统中检索服务定位器 - ZF2

时间:2016-03-17 12:56:02

标签: php zend-framework zend-framework2 deprecated zend-framework3

我正在开发一个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;
}

我已经尝试了一切,有人知道我该做什么吗?

2 个答案:

答案 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);
    }
}