我读了很多关于这个的话题,我似乎找不到解决我问题的方法。在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