目前我有这样的Types.php:
namespace Application\GraphQL;
use Application\GraphQL\Type\NodeType;
use Application\GraphQL\Type\QueryType;
use GraphQL\Type\Definition\NonNull;
use GraphQL\Type\Definition\Type;
use Application\GraphQL\Type\PersonType;
/**
* Class Types
*
* Acts as a registry and factory for your types.
*
* As simplistic as possible for the sake of clarity of this example.
* Your own may be more dynamic (or even code-generated).
*
* @package GraphQL\Examples\Blog
*/
class Types
{
private static $query;
private static $person;
private static $node;
public static function person()
{
return self::$person ?: (self::$person = new PersonType());
}
/**
* @return QueryType
*/
public static function query()
{
return self::$query ?: (self::$query = new QueryType());
}
/**
* @return NodeType
*/
public static function node()
{
return self::$node ?: (self::$node = new NodeType());
}
/**
* @return \GraphQL\Type\Definition\IDType
*/
public static function id()
{
return Type::id();
}
/**
* @return \GraphQL\Type\Definition\StringType
*/
public static function string()
{
return Type::string();
}
/**
* @param Type $type
* @return NonNull
*/
public static function nonNull($type)
{
return new NonNull($type);
}
}
在 query() 函数中,它创建 QueryType 实例。我添加到 QueryType 构造函数 PersonTable 模型类,以便它可以从数据库中查询人员。
查询类型.php
public function __construct(PersonTable $table)
{
$config = [
'name' => 'Query',
'fields' => [
'person' => [
'type' => Types::person(),
'description' => 'Returns person by id',
'args' => [
'id' => Types::nonNull(Types::id())
]
],
'hello' => Type::string()
],
'resolveField' => function($val, $args, $context, ResolveInfo $info) {
return $this->{$info->fieldName}($val, $args, $context, $info);
}
];
$this->table = $table;
parent::__construct($config);
}
我在 module\Application\src\Module.php 中设置了工厂:
/**
* @link http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Application;
use Application\Model\PersonTable;
use Application\Model\Person;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
class Module
{
const VERSION = '3.0.2dev';
public function getConfig()
{
return include __DIR__ . '/../config/module.config.php';
}
// Add this method:
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Model\PersonTable' => function($sm) {
$tableGateway = $sm->get('PersonTableGateway');
$table = new PersonTable($tableGateway);
return $table;
},
'PersonTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Person());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
}
我正在做这个没有任何框架的例子:
https://github.com/webonyx/graphql-php/tree/master/examples/01-blog
所以问题是 - 如何使用注入的 PersonTable 实例创建 queryType 实例?我应该以某种方式从工厂获取 PersonTable 实例,但我不明白如何。
更新:
我决定尝试将 QueryType 注入控制器。创建了这样的功能:
public function __construct(QueryType $queryType)
{
$this->queryType = $queryType;
}
现在 module\Application\src\Module.php getServiceConfig 看起来像这样:
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Model\PersonTable' => function($sm) {
$tableGateway = $sm->get('PersonTableGateway');
$table = new PersonTable($tableGateway);
return $table;
},
'PersonTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Person());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
QueryType::class => function ($sm) {
return new QueryType($sm->get(PersonTable::class));
}
// when putting in namespace does not find??????????
//QueryType::class => Application\GraphQL\Type\Factories\QueryTypeFactory::class
//QueryType::class => \QueryTypeFactory::class
),
);
}
但我得到错误:
可捕获的致命错误:传递给 Application\Controller\IndexController::__construct() 的参数 1 必须是 Application\GraphQL\Type\QueryType 的实例,没有给出,在 E:\projektai\php projektai\htdocs\graphQL_zend_3\vendor\ 中调用zendframework\zend-servicemanager\src\Factory\InvokableFactory.php 在第 32 行并在 E:\projektai\php projektai\htdocs\graphQL_zend_3\module\Application\src\Controller\IndexController.p 中定义
如果我在该功能中配置,怎么能不给出?
如果我可以注入控制器,那么我打算这样做:
$schema = new Schema([
//'query' => Types::query()
'query' => $this->queryType
]);
所以我不需要调用返回 QueryType 实例的 query() 函数。
然后将 PersonTable 自动注入到 QueryType 类中。
更新:
我创建了工厂,类似于答案:
class QueryTypeFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new QueryType($container->get(PersonTable::class));
}
}
在 IndexController 我有构造函数:
public function __construct(QueryType $queryType)
{
$this->queryType = $queryType;
}
在 Module.php 我使用这个工厂:
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Model\PersonTable' => function($sm) {
$tableGateway = $sm->get('PersonTableGateway');
$table = new PersonTable($tableGateway);
return $table;
},
'PersonTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Person());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
// QueryType::class => function ($sm) {
// //return new QueryType($sm->get(PersonTable::class));
//
// }
//QueryType::class => Application\GraphQL\Type\Factories\QueryTypeFactory::class
//QueryType::class => \QueryTypeFactory::class
QueryType::class => QueryTypeFactory::class
),
);
}
它根本不起作用,我收到错误:
可捕获的致命错误:传递给 Application\Controller\IndexController::__construct() 的参数 1 必须是 Application\GraphQL\Type\QueryType 的实例,没有给出,在 E:\projektai\php projektai\htdocs\graphQL_zend_3\vendor\ 中调用zendframework\zend-servicemanager\src\Factory\InvokableFactory.php 在第 32 行并在 E:\projektai\php projektai\htdocs\graphQL_zend_3\module\Application\src\Controller\IndexController.php 在线定义
我也尝试过这种方式:
$queryTypeFactory = new QueryTypeFactory();
// GraphQL schema to be passed to query executor:
$schema = new Schema([
//'query' => Types::query()
//'query' => $this->queryType
// 'query' => $queryType
'query' => $queryTypeFactory()
]);
但是 $queryTypeFactory() 需要参数 $container。这不是我想要的,我猜。我应该能够在不传递参数的情况下创建一个实例。
我希望可以在工厂数组中使用 QueryType::class 作为键。它将使用设置的全名空间创建:
use Application\GraphQL\Type\QueryType;
在索引控制器中,我也称之为 use 语句。