我在BITGoogleBundle中有一项服务,它依赖于路由器服务来生成特定的回调路由:
BIT\GoogleBundle\Google\GoogleClient::setUp
如果我在构造函数中调用此方法,则会出现此错误:
ServiceCircularReferenceException: Circular reference detected for service
"security.context", path: "profiler_listener -> profiler -> security.context ->
security.authentication.manager -> bit_google.client -> routing.loader ->
assetic.asset_manager -> twig".
但如果我把它称为其他服务的正常功能,那就可以了。
这是什么方法来避免这个错误?
修改
google.xml
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="bit_google.client" class="%bit_google.client.class%">
<argument type="collection">
<argument key="app_name">%bit_google.app_name%</argument>
<argument key="client_id">%bit_google.client_id%</argument>
<argument key="client_secret">%bit_google.client_secret%</argument>
<argument key="simple_api_access">%bit_google.simple_api_access%</argument>
<argument key="state">%bit_google.state%</argument>
<argument key="access_type">%bit_google.access_type%</argument>
<argument key="scopes">%bit_google.scopes%</argument>
<argument key="approval_prompt">%bit_google.approval_prompt%</argument>
<argument key="callback_route">%bit_google.callback_route%</argument>
</argument>
<argument type="service" id="session"/>
<argument type="service" id="router"/>
</service>
<service id="bit_google.user" class="%bit_google.user.class%">
<argument type="service" id="bit_google.client"/>
</service>
<service id="bit_google.contact" class="%bit_google.contact.class%">
<argument type="service" id="bit_google.client"/>
</service>
<service id="bit_google.url" class="%bit_google.url.class%">
<argument type="service" id="bit_google.client"/>
</service>
<service id="bit_google.twig" class="%bit_google.twig.class%">
<argument type="service" id="service_container"/>
<argument type="service" id="bit_google.client"/>
<tag name="twig.extension"/>
</service>
</services>
</container>
GoogleClient.php
/*
* This file is part of the BITGoogleBundle package.
*
* (c) bitgandtter <http://bitgandtter.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace BIT\GoogleBundle\Google;
use Google_Client;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Router;
/**
* Implements Symfony2 service for Google_Client.
*/
class GoogleClient extends Google_Client
{
const PREFIX = '_bit_google_';
protected static $supportedKeys = array('access_token', 'user_id');
private $config;
private $session;
private $router;
private $prefix;
public function __construct(array $config, Session $session, Router $router, $prefix = self::PREFIX)
{
parent::__construct();
$this->config = $config;
$this->session = $session;
$this->router = $router;
$this->prefix = $prefix;
$this->setUp();
}
public function setup()
{
$this->setApplicationName($this->config ["app_name"]);
$this->setClientId($this->config ["client_id"]);
$this->setClientSecret($this->config ["client_secret"]);
$this->setState($this->config ["state"]);
$this->setAccessType($this->config ["access_type"]);
$this->setApprovalPrompt($this->config ["approval_prompt"]);
if ($this->config ["simple_api_access"]) {
$this->setDeveloperKey($this->config ["simple_api_access"]);
}
$scopes = array();
$scopes[] = "openid";
if ($this->config ["scopes"]["profile"]) {
$scopes[] = "profile";
$scopes[] = "https://www.googleapis.com/auth/plus.login";
$scopes[] = "https://www.googleapis.com/auth/plus.me";
}
if ($this->config ["scopes"]["email"]) {
$scopes[] = "email";
$scopes[] = "https://www.googleapis.com/auth/plus.profile.emails.read";
}
if ($this->config ["scopes"]["contact"]) {
$scopes[] = "https://www.google.com/m8/feeds";
}
$this->requestedScopes = $scopes;
$this->setRedirectUri($this->router->generate($this->config ["callback_route"], array(), Router::ABSOLUTE_URL));
$this->getAccessToken();
}
public function getAccessToken()
{
parent::setAccessToken($this->getPersistentData('access_token'), null);
return parent::getAccessToken();
}
/**
* Get the data for $key
*
* @param string $key The key of the data to retrieve
* @param null $default The default value to return if $key is not found
*
* @return mixed
*/
public function getPersistentData($key, $default = null)
{
$this->checkSupportedKeys($key);
return $this->session->get($this->constructSessionVariableName($key), $default);
}
private function constructSessionVariableName($key)
{
return $this->prefix . implode('_', array('g', $this->config ["client_id"], $key));
}
/**
* Clear the data with $key from the persistent storage
*
* @param string $key
*
* @return void
*/
public function clearPersistentData($key)
{
$this->checkSupportedKeys($key);
$this->session->remove($this->constructSessionVariableName($key));
}
private function checkSupportedKeys($key)
{
if (!in_array($key, self::$supportedKeys)) {
throw new \Google_Exception('Unsupported key passed to getPersistentData.');
}
}
/**
* Clear all data from the persistent storage
*
* @return void
*/
public function clearAllPersistentData()
{
foreach ($this->session->all() as $k => $v) {
if (0 !== strpos($k, $this->prefix)) {
continue;
}
$this->session->remove($k);
}
}
public function setAccessToken($accessToken)
{
parent::setAccessToken($accessToken);
$this->setPersistentData('access_token', $accessToken);
}
/**
* Stores the given ($key, $value) pair, so that future calls to
* getPersistentData($key) return $value.
* This call may be in another request.
*
* @param string $key
* @param array $value
*
* @return void
*/
public function setPersistentData($key, $value)
{
$this->checkSupportedKeys($key);
$this->session->set($this->constructSessionVariableName($key), $value);
}
}
所有这一切都是我在github上的回购中称为GoogleBundle的一部分,在那里你可以找到所有的代码,但上面的那个有问题的