laravel 查询构造器中类中的构造函数传参是可以自动new一个传递进去的吗

new一个对象数组,只能调用默认构造函数么,不能带有参数的?
[问题点数:40分,结帖人wentis]
new一个对象数组,只能调用默认构造函数么,不能带有参数的?
[问题点数:40分,结帖人wentis]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2015年1月 C/C++大版内专家分月排行榜第二2012年3月 C/C++大版内专家分月排行榜第二2011年11月 C/C++大版内专家分月排行榜第二2010年6月 C/C++大版内专家分月排行榜第二2010年5月 C/C++大版内专家分月排行榜第二
2011年4月 C/C++大版内专家分月排行榜第三2011年2月 C/C++大版内专家分月排行榜第三2010年8月 C/C++大版内专家分月排行榜第三
2012年11月 挨踢职涯大版内专家分月排行榜第二2011年9月 Linux/Unix社区大版内专家分月排行榜第二
2012年1月 Linux/Unix社区大版内专家分月排行榜第三2011年8月 C/C++大版内专家分月排行榜第三2011年8月 Linux/Unix社区大版内专家分月排行榜第三2010年4月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。php7扩展开发[3]类构造函数传参 - 推酷
php7扩展开发[3]类构造函数传参
php7扩展开发[3]类构造函数传参
03 Feb 2016
1.需要实现的细节
实现一个person类 ,实现一个doing方法和saying方法
在构造方法中传递一个数组,在doing中打印此数组
saying方法中,构建一个空数组,返回,不需要传参。
2.class扩展
2.1创建类的扩展:
[root@bogon ext]# cd /usr/local/src/php-7.0.3/ext
[root@bogon ext]# ./ext_skel --extname=person
2.2 修改配置
[root@bogon ext]# vim person/config.m4
WITH(person, for person support,
dnl Make sure that the comment is aligned:
dnl [ --with-person Include person support])
WITH(person, for person support,
dnl Make sure that the comment is aligned:
[ --with-person Include person support])
2.3 实现代码
在php_person.h头中加上
extern zend_class_entry *person_ce;
PHP_METHOD(person_ce,__construct);
PHP_METHOD(person_ce,saying);
PHP_METHOD(person_ce,doing);
在person.c头中加上
ZEND_BEGIN_ARG_INFO_EX(global_config_arg, 0, 0, 1)
ZEND_ARG_INFO(0, global_config)
ZEND_END_ARG_INFO()
* 声明构造函数
ZEND_METHOD(person,__construct){
zval *array_config;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, &a&, &array_config) == FAILURE) {
RETURN_NULL();
//php_var_dump( &array_config,1 TSRMLS_CC);
zend_update_property(person_ce, getThis(), &config&, sizeof(&config&)-1, array_config TSRMLS_CC);
* 声明析造函数
ZEND_METHOD(person,__destruct){
zend_printf(&destruct\n&);
ZEND_METHOD(person,doing){
//array_init(return_value);
*array_config;
rv; //php &=7.0
array_config = zend_read_property(person_ce, getThis(), &config&, sizeof(&config&)-1, 0, &rv TSRMLS_DC);
if( Z_TYPE_P(array_config) == IS_NULL || Z_TYPE_P(array_config) != IS_ARRAY ){
//zend_error(E_ERROR, &framework config error!&);
RETURN_FALSE;
//php_var_dump(&array_config, 1 TSRMLS_CC);
RETURN_ZVAL(array_config, 1, 0);
//zend_printf(&doing\n&);
ZEND_METHOD(person,saying){
if (zend_parse_parameters_none() == FAILURE) {
RETURN_FALSE;
array_init(return_value);
//zend_printf(&saying\n&);
//这个函数需要加上声明,去掉了没用的test函数
const zend_function_entry person_functions[] = {
ZEND_ME(person, __construct, global_config_arg, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
ZEND_ME(person,doing,NULL,ZEND_ACC_PUBLIC)
ZEND_ME(person,saying,NULL,ZEND_ACC_PUBLIC)
ZEND_ME(person,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
PHP_FE_END
/* Must be the last line in person_functions[] */
//将类和方法注册到zend
PHP_MINIT_FUNCTION(person)
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, &person&, person_functions);
person_ce = zend_register_internal_class(&ce TSRMLS_CC);
zend_declare_property_null(person_ce,&saying&,strlen(&saying&),ZEND_ACC_PUBLIC);
zend_declare_property_null(person_ce,&doing&,strlen(&doing&),ZEND_ACC_PUBLIC);
return SUCCESS;
* [root@bogon hello]# [root@localhost person]# ./configure && make && make install
2.5 扩展安装
1. 改更php.ini 加上[person] extenstion=person.so
2.6 扩展使用
[root@bogon tests]# cat test.php
$n = new person(array('key'=&'value'));
var_dump($n-&saying('error'));
var_dump($n-&saying());
var_dump($n-&doing());
[root@localhost tests]# php test.php
PHP Warning:
person::saying() expects exactly 0 parameters, 1 given in /usr/local/src/php-7.0.3/ext/person/tests/test.php on line 5
bool(false)
array(0) {
array(1) {
string(5) &value&
3.引用宏说明
3.1 定义参数宏 Zend/zend_API.h
[root@bogon php-7.0.3]# grep -A 10
'ZEND_BEGIN_ARG_INFO_EX' ./Zend/*.h
#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args)
static const zend_internal_arg_info name[] = { \
{ (const char*)(zend_uintptr_t)(required_num_args), NULL, 0, return_reference, 0, 0 },
#define ZEND_BEGIN_ARG_INFO(name, _unused)\
ZEND_BEGIN_ARG_INFO_EX(name, 0, ZEND_RETURN_VALUE, -1)
#define ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) //开始参数块定义,pass_rest_by_reference为1时,强制所有参数为引用类型
ZEND_END_ARG_INFO() //结束参数块定义
ZEND_ARG_INFO //声明普通参数,可以用来表示PHP中的int, float, double, string等基本数据类型
ZEND_ARG_OBJ_INFO //声明对象类型的参数
ZEND_ARG_ARRAY_INFO //声明数组类型的参数
ZEND_ARG_PASS_INFO(pass_by_ref)
//pass_by_ref为1时,强制设置后续的参数为引用类型
zend_internal_arg_info结构定义在./Zend/zend_compile.h:
typedef struct _zend_internal_arg_info {
const char * //参数的名称
const char *class_ //当参数类型为类时,指定类的名称
zend_uchar type_
zend_uchar pass_by_//是否设置为引用,即使用&操作符
zend_bool allow_ //是否允许设置为null
zend_bool is_
} zend_internal_arg_
3.2 定义返回值的宏 Zend/zend_API.h
#define RETVAL_BOOL(b)
ZVAL_BOOL(return_value, b)
#define RETVAL_NULL()
ZVAL_NULL(return_value)
#define RETVAL_LONG(l)
ZVAL_LONG(return_value, l)
#define RETVAL_DOUBLE(d)
ZVAL_DOUBLE(return_value, d)
#define RETVAL_STR(s)
ZVAL_STR(return_value, s)
#define RETVAL_INTERNED_STR(s)
ZVAL_INTERNED_STR(return_value, s)
#define RETVAL_NEW_STR(s)
ZVAL_NEW_STR(return_value, s)
#define RETVAL_STR_COPY(s)
ZVAL_STR_COPY(return_value, s)
#define RETVAL_STRING(s)
ZVAL_STRING(return_value, s)
#define RETVAL_STRINGL(s, l)
ZVAL_STRINGL(return_value, s, l)
#define RETVAL_EMPTY_STRING()
ZVAL_EMPTY_STRING(return_value)
#define RETVAL_RES(r)
ZVAL_RES(return_value, r)
#define RETVAL_ARR(r)
ZVAL_ARR(return_value, r)
#define RETVAL_OBJ(r)
ZVAL_OBJ(return_value, r)
#define RETVAL_ZVAL(zv, copy, dtor)
ZVAL_ZVAL(return_value, zv, copy, dtor)
#define RETVAL_FALSE
ZVAL_FALSE(return_value)
#define RETVAL_TRUE
ZVAL_TRUE(return_value)
#define RETURN_BOOL(b)
{ RETVAL_BOOL(b); }
#define RETURN_NULL()
{ RETVAL_NULL();}
#define RETURN_LONG(l)
{ RETVAL_LONG(l); }
#define RETURN_DOUBLE(d)
{ RETVAL_DOUBLE(d); }
#define RETURN_STR(s)
{ RETVAL_STR(s); }
#define RETURN_INTERNED_STR(s)
{ RETVAL_INTERNED_STR(s); }
#define RETURN_NEW_STR(s)
{ RETVAL_NEW_STR(s); }
#define RETURN_STR_COPY(s)
{ RETVAL_STR_COPY(s); }
#define RETURN_STRING(s)
{ RETVAL_STRING(s); }
#define RETURN_STRINGL(s, l)
{ RETVAL_STRINGL(s, l); }
#define RETURN_EMPTY_STRING()
{ RETVAL_EMPTY_STRING(); }
#define RETURN_RES(r)
{ RETVAL_RES(r); }
#define RETURN_ARR(r)
{ RETVAL_ARR(r); }
#define RETURN_OBJ(r)
{ RETVAL_OBJ(r); }
#define RETURN_ZVAL(zv, copy, dtor)
{ RETVAL_ZVAL(zv, copy, dtor); }
#define RETURN_FALSE
{ RETVAL_FALSE; }
#define RETURN_TRUE
{ RETVAL_TRUE; }
a)返回数组
array_init(return_value);//初始化return_value成数组,此操作完后就可以返回一个空的数组
b)返回object
object_init(return_value);//初始化return_value成Object,此操作完成后返回一个空的对像
3.3 类访问控制掩码 ./Zend/zend_compile.h
/* method flags (types) */
#define ZEND_ACC_STATIC
#define ZEND_ACC_ABSTRACT
#define ZEND_ACC_FINAL
#define ZEND_ACC_IMPLEMENTED_ABSTRACT
/* class flags (types) */
/* ZEND_ACC_IMPLICIT_ABSTRACT_CLASS is used for abstract classes (since it is set by any abstract method even interfaces MAY have it s
/* ZEND_ACC_EXPLICIT_ABSTRACT_CLASS denotes that a class was explicitly defined as abstract by using the keyword. */
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
#define ZEND_ACC_INTERFACE
#define ZEND_ACC_TRAIT
#define ZEND_ACC_ANON_CLASS
#define ZEND_ACC_ANON_BOUND
/* method flags (visibility) */
/* The order of those must be kept - public & protected & private */
#define ZEND_ACC_PUBLIC
#define ZEND_ACC_PROTECTED
#define ZEND_ACC_PRIVATE
#define ZEND_ACC_PPP_MASK
(ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
#define ZEND_ACC_CHANGED
#define ZEND_ACC_IMPLICIT_PUBLIC
/* method flags (special method detection) */
#define ZEND_ACC_CTOR
#define ZEND_ACC_DTOR
#define ZEND_ACC_CLONE
请尊重本人劳动成功,可以随意转载但保留以下信息
作者:岁月经年
时间:2016年03月
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Laravel实现构造函数自动依赖注入的方法
作者:小谈博客
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Laravel实现构造函数自动依赖注入的方法,涉及Laravel构造函数自动初始化的相关技巧,需要的朋友可以参考下
本文实例讲述了Laravel实现构造函数自动依赖注入的方法。分享给大家供大家参考,具体如下:
在Laravel的构造函数中可以实现自动依赖注入,而不需要实例化之前先实例化需要的类,如代码所示:
namespace Lio\Http\Controllers\F
use Lio\Forum\Replies\ReplyR
use Lio\Forum\Threads\ThreadC
use Lio\Forum\Threads\ThreadCreatorL
use Lio\Forum\Threads\ThreadDeleterL
use Lio\Forum\Threads\ThreadF
use Lio\Forum\Threads\ThreadR
use Lio\Forum\Threads\ThreadUpdaterL
use Lio\Http\Controllers\C
use Lio\Tags\TagR
class ForumThreadsController extends Controller implements ThreadCreatorListener, ThreadUpdaterListener, ThreadDeleterListener
protected $
protected $
protected $currentS
protected $threadC
public function __construct(
ThreadRepository $threads,
ReplyRepository $replies,
TagRepository $tags,
ThreadCreator $threadCreator
$this-&threads = $
$this-&tags = $
$this-&threadCreator = $threadC
$this-&replies = $
注意构造函数中的几个类型约束,其实并没有地方实例化这个Controller并把这几个类型的参数传进去,Laravel会自动检测类的构造函数中的类型约束参数,并自动识别是否初始化并传入。
源码vendor/illuminate/container/Container.php中的build方法:
$constructor = $reflector-&getConstructor();
dump($constructor);
这里会解析类的构造函数,在这里打印看:
它会找出构造函数的参数,再看完整的build方法进行的操作:
public function build($concrete, array $parameters = [])
// If the concrete type is actually a Closure, we will just execute it and
// hand back the results of the functions, which allows functions to be
// used as resolvers for more fine-tuned resolution of these objects.
if ($concrete instanceof Closure) {
return $concrete($this, $parameters);
$reflector = new ReflectionClass($concrete);
// If the type is not instantiable, the developer is attempting to resolve
// an abstract type such as an Interface of Abstract Class and there is
// no binding registered for the abstractions so we need to bail out.
if (! $reflector-&isInstantiable()) {
$message = "Target [$concrete] is not instantiable.";
throw new BindingResolutionContractException($message);
$this-&buildStack[] = $
$constructor = $reflector-&getConstructor();
// If there are no constructors, that means there are no dependencies then
// we can just resolve the instances of the objects right away, without
// resolving any other types or dependencies out of these containers.
if (is_null($constructor)) {
array_pop($this-&buildStack);
return new $
$dependencies = $constructor-&getParameters();
// Once we have all the constructor's parameters we can create each of the
// dependency instances and then use the reflection instances to make a
// new instance of this class, injecting the created dependencies in.
$parameters = $this-&keyParametersByArgument(
$dependencies, $parameters
$instances = $this-&getDependencies(
$dependencies, $parameters
array_pop($this-&buildStack);
return $reflector-&newInstanceArgs($instances);
具体从容器中获取实例的方法:
protected function resolveClass(ReflectionParameter $parameter)
return $this-&make($parameter-&getClass()-&name);
// If we can not resolve the class instance, we will check to see if the value
// is optional, and if it is we will return the optional parameter value as
// the value of the dependency, similarly to how we do this with scalars.
catch (BindingResolutionContractException $e) {
if ($parameter-&isOptional()) {
return $parameter-&getDefaultValue();
框架底层通过Reflection反射为开发节省了很多细节,实现了自动依赖注入。这里不做继续深入研究了。
写了一个模拟这个过程的类测试:
class kulou
class junjun
class tanteng
public function __construct(kulou $kulou,junjun $junjun)
$this-&kulou = $
$this-&junjun = $
//$tanteng = new tanteng(new kulou(),new junjun());
$reflector = new ReflectionClass('tanteng');
$constructor = $reflector-&getConstructor();
$dependencies = $constructor-&getParameters();
print_r($dependencies);
原理是通过ReflectionClass类解析类的构造函数,并且取出构造函数的参数,从而判断依赖关系,从容器中取,并自动注入。
转自:小谈博客 /2016/01/laravel-construct-ioc/
更多关于Laravel相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》、《》、《》及《》
希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 laravel 构造函数 的文章

 

随机推荐