错误:在非对象上调用成员函数has()



我读了很多关于这个的话题,我似乎找不到解决我问题的方法。在vendor/symfony/symfony/src/symfony/Bundle/FrameworkBundle/Controller/Controller.php的第291行中,调用一个成员函数has()在一个非对象上。

public function getDoctrine()
{
    if (!$this->container->has('doctrine')) {
        throw new LogicException('The DoctrineBundle is not   registered in your application.');
    }

}

这是主控制器

namespace AcmeIndexBundleController;
use SymfonyComponentHttpFoundationSessionSession;
use SymfonyComponentHttpFoundationRequest;
use SymfonyBundleFrameworkBundleControllerController;
use AcmeIndexBundleEntitySlotmachineSpin;
use AcmeIndexBundleEntitySlotmachineReels;
use AcmeIndexBundleEntitySlotmachinePrizes;
use AcmeIndexBundleSlotsUsersSlots;
use AcmeIndexBundleSlotsSlotsMachineSlots;

class SpinController extends Controller  {

    public function indexAction(Request $request)
    {
        $session = $request->getSession();
        $slotsmachine = new SlotsMachineSlots();
        //$request = Request::createFromGlobals();
        $_machineName = $request->request->get('machine_name');
        $machineName = $slotsmachine->GetMachineName((isset($_machineName)?$_machineName : "default" ));
        $_bet = $request->request->get('bet');
        $bet = (isset($_bet) ? $_bet : $slotsmachine->MinBet($machineName)); // Should always be set, but just in case.
        $bet = min(max($slotsmachine->MinBet($machineName), $bet), $slotsmachine->MaxBet($machineName));
        $_windowID = $request->request->get('windowID');
        $windowID = (isset($_windowID) ? $_windowID : "");
        // Validate
        $error = "";
        $userID = UsersSlots::LoggedUserID();
        try { //DB::BeginTransaction();
            $em = $this->getDoctrine()->getManager();
            $em->getConnection()->beginTransaction();
            if (!$userID) {
                $error = 'loggedOut';
            } else if(!UsersSlots::HasEnoughCredits($userID, $bet)) {
                $error = "You don't have enough credits for this bet";
            }
            if ($error != "") {
                echo json_encode(array('success'=>false, 'error'=>$error));
                return;
            }
            // Do the charging, spinning and crediting
            UsersSlots::DeductCredits($userID, $bet);
            UsersController::IncrementSlotMachineSpins($userID);
            $data = SlotsMachineSlots::Spin($userID, $machineName, $bet, $windowID);
            if ($data['prize'] != null) {
                UsersSlots::IncreaseCredits($userID, $data['prize']['payoutCredits']);
                UsersSlots::IncreaseWinnings($userID, $data['prize']['payoutWinnings']);
                $data['lastWin'] = $data['prize']['payoutWinnings'];
            }
            $data['success'] = true;
            $userData = UsersSlots::GetUserData($userID);
            $data['credits'] = (float) $userData['credits'];
            $data['dayWinnings'] = (float) $userData['day_winnings'];
            $data['lifetimeWinnings'] = (float) $userData['lifetime_winnings'];
            echo json_encode($data);
            $em->getConnection()->commit();
        } catch (Exception $e) {
                $em->getConnection()->rollback(); 
                throw $e; 
            }
        // Sample responses that allow you to test your CSS and JS
        // Comment the entire try/catch block above, and uncomment one of these at a time.
        // Regular spin, no prize
        //echo json_encode(array('success' => true, 'reels' => array(1, 2.5, 3), 'prize' => null, 'credits' => 99, 'dayWinnings' => 10, 'lifetimeWinnings' => 500));
        // Prize, pays credits only
        //echo json_encode(array('success' => true, 'reels' => array(1, 2.5, 3), 'prize' => array('id' => 1, 'payoutCredits' => 10, 'payoutWinnings' => 0), 'credits' => 19, 'dayWinnings' => 00, 'lifetimeWinnings' => 500));
        // Prize, pays winnings only
        //echo json_encode(array('success' => true, 'reels' => array(1, 2.5, 3), 'prize' => array('id' => 2, 'payoutCredits' => 0, 'payoutWinnings' => 100), 'credits' => 9, 'dayWinnings' => 100, 'lifetimeWinnings' => 600));
        // Error (logged out)
        //echo json_encode(array('success' => false, 'error' => 'loggedOut'));
        // Error (other)
        //echo json_encode(array('success' => false, 'error' => 'You do not have enough credits for this spin'));
        //return new Response(json_encode(array('spinData' => $spinData)));
    }

}

这是正在使用的服务。

acme.controller.spin:
    class: ImaginerIndexBundleControllerSpinController
    calls:
        - [setContainer, ["@service_container"]]

我确定问题是学说容器不存在,这就是我遇到问题的原因。

任何帮助都是感激的。谢谢!

Sundar的响应在我的案例中起作用。我有同样的问题,现在它工作了。

当你无论如何都不能获得控制器方法时,你可以在__construct中注入你需要的服务,并在服务参数中给出它们,例如:

在yml:

funny.controller.service:
        class: AppBundleControllerFunnyController
        arguments: ["@doctrine.orm.entity_manager"]

:

use DoctrineORMEntityManager;
/**
* @Route("/funny", service="funny.controller.service")
*/
class FunnyController extends Controller
{
 private $em;
 public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

之后使用$this->em代替$this->getDoctrine()->getManager();

问题是这里的容器没有被注入到控制器中。

通常情况下,如果你扩展了symfony BundleFrameworkBundleControllerController,而它本身扩展了symfony ComponentDependencyInjectionContainerAware,那么symfony会自动执行此操作。

 use SymfonyBundleFrameworkBundleControllerController;
 class YourController extends Controller

容器被注入到控制器(如果没有显式定义为服务),使用setter注入方法调用setContainer(),并以容器为参数。

现在,当你将控制器配置为服务时,你需要将setContainer调用添加到你的服务配置中。

services:
  database_controller:
    class:  FuelFormBundleControllerDatabaseController
    calls:
        - [setContainer, ["@service_container"]]

之后清除缓存

credit: nifr

最新更新