仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1507|回复: 19
打印 上一主题 下一主题

[学习教程] PHP编程:深切PHP利用技能之变量

[复制链接]
再见西城 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-2-3 23:34:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
学习数据库了,MYSQL可算是PHP的黄金搭档了,不过,虽然话是这么说,你也可能恨不得把MYSQL给生吞活剥了,因为这一行一列的东东简直让自己头晕目眩。      尽人皆知,PHP与其他剧本言语一样,属于弱变量类型的言语。同时PHP自己也是经由过程C言语来完成。本文次要引见PHP外部是若何完成弱变量类型的,而且据此剖析在PHP开辟中需求注重的一些利用手艺。个中会重点剖析PHP中的copy on write机制和援用相干方面的话题。 本章节属于《深切PHP利用技能》的第一局部。
    若何完成弱变量
    在懂得PHP完成弱变量类型之前,可以先思虑下:若何经由过程C/C++来完成弱变量类型的后果呢?
    这个成绩我在BIT培训课上根基上有两种谜底:
    办法1:采取C++的承继机制。起首界说一个基本类型
    Class Var
    {
    }
    然后基于Var,派生出分歧的子类型IntVar/FloatVar/StringVar等等。
    办法2:基于C言语的 Struct。个中一个字段用于标识类型,别的一个字段用于存储数据,因为数据如果各类类型,所以凡是需求采取指针
    好比:
    struct var {
    Int type;
    Void *data;
    };
    两种思绪自己并没有太大区分,也都根基上可以知足需求。在PHP中采取了第二种思绪,而且做了对照多的优化。在PHP中,一切的变量城市对应统一品种型zval,个中zval也就是struct _zval_struct,详细界说以下:
    typedef union _zvalue_value {
    long lval; /* long value */
    double dval; /* double value */
    struct {
    char *val;
    int len;
    } str;
    HashTable *ht; /* hash table value */
    zend_object_value obj;
    } zvalue_value;
    struct _zval_struct {
    /* Variable information */
    zvalue_value value; /* value */
    zend_uint refcount;
    zend_uchar type; /* active type */
    zend_uchar is_ref;
    };
    从zval可以看出,PHP在细节方面切实其实做了很多优化的工夫。
    1.zend_uchar type。采取uchar节俭内存。
    2.zvalue_value value; 采取union来交换void *,如许一样能节俭空间,而且比void *更能表义明晰。
    3.在字符串类型中,默许保存了字符串的长度。如许很轻易做到字符串的二进制平安,而且在盘算字符串长度的时分不需求停止扫描。
    察看PHP弱变量的完成,也会有以下困惑:
    1.为何会没有int类型呢?其其实PHP中是有的,只是说默许int数据就保留在long中。
    2.资本类型咋体现的呢?资本在PHP外部其实就是一数字。具体后续会引见。
    3.refcount和is_ref是干吗的呢?呵呵,这就是第二局部要引见的了。
    Reference counting & Copy-on-Write
    PHP和其他言语相似,在其语法中有两种赋值体例:援用赋值和非援用赋值(通俗的==赋值)。
    <?php
    $a = 1;
    $b = $a;//非援用赋值
    $c = &$a;//援用赋值
    ?>
    援用赋值和非援用赋值在PHP外部是若何完成的呢?一种凡是的熟悉是:“援用赋值就是两个变量对应统一个Zval,非援用赋值则是直接发生一个新的zval,同时把对应的值直接copy过去。”也就是该代码的内存布局以下:
    
  

                               
登录/注册后可看大图
   
    (该图是大多半人以为的PHP内存布局,是毛病的)
    如许切实其实可以知足大局部情形下的需求,但明显不是最好的处理计划,特别是在内存办理上,好比说以下代码就会显得十分的低效。
    <?php
    $arr = array(...);//界说一个十分大的PHP数组
    myfunc($arr);//每个函数挪用都是一次隐性的非援用赋值
    myfunc($arr);
    ?>
    由于每次函数挪用会停止一次内存dump,而大内存的内存dump长短常耗CPU的。在C言语中,一种处理计划是采取指针,一切函数挪用尽可能传递指针。切实其实很天真高效,但也很难保护~指针可以说是C言语法式员心头的痛(固然也是福~^_^)。还有一种更初级更无效的办法是采取援用计数(Reference counting)。
    在PHP中,也能够采取援用来处理如许的成绩,但你见过采取在PHP中大批利用援用的吗?明显很少。
    在PHP内核中,Zval的完成恰是采取了援用计数的概念,说起援用计数就不能不谈到copy-on-write 机制。如许后面谈到的refcount和is_ref就有感化了。
    refcount:援用次数。在zval初始创立的时分就为1。每增添一个援用,则refcount ++。
    is_ref:用于暗示一个zval是不是是援用形态。zval初始化的情形下会是0,暗示不是援用。
    在Zend/Zend.h外部有一些关于ZVAL的宏界说,外面对照明晰的解析了援用计数的一些划定规矩,个中重点存眷以下几个宏界说
    #define INIT_PZVAL(z) \
    (z)->refcount = 1; \
    (z)->is_ref = 0;
    #define SEPARATE_ZVAL_IF_NOT_REF(ppzv) \//非援用下的变量分别
    if (!PZVAL_IS_REF(*ppzv)) { \
    SEPARATE_ZVAL(ppzv); \
    }
    #define SEPARATE_ZVAL_TO_MAKE_IS_REF(ppzv) \//非援用下的变量分别,而且设置援用
    if (!PZVAL_IS_REF(*ppzv)) { \
    SEPARATE_ZVAL(ppzv); \
    (*(ppzv))->is_ref = 1; \
    }
    #define SEPARATE_ARG_IF_REF(varptr) \ //援用下的变量分别
    if (PZVAL_IS_REF(varptr)) { \
    zval *original_var = varptr; \
    ALLOC_ZVAL(varptr); \
    varptr->value = original_var->value; \
    varptr->type = original_var->type; \
    varptr->is_ref = 0; \
    varptr->refcount = 1; \
    zval_copy_ctor(varptr); \
    } else { \
    varptr->refcount++; \
    }
    这外面谈到两个主要的概念:
    1、非援用下的变量分别。
    非援用下的变量分别,是指在一堆非援用变量中拔出援用的情形下,在PHP外部停止的一种内存操作。以上面的列子来看:
    $a = 1;
    $b = $a;
    $c = &$b;
    在前两句履行以后,内存布局以下图
    
  

                               
登录/注册后可看大图
   
    在第三句 $c = &$b;语句中则会履行“非援用下的变量分别。”,详细步调是:
    将b分别出来,同时把a对应的zval的refcount-1。
    copy 出一个新的zval,并把zval的is_ref设置成1.
    把C指向这个新的zval,同时refcount ++
    终究后果以下图:
    
  

                               
登录/注册后可看大图
   
    2、援用下的变量分别。
    援用下的变量分别,是指在一堆援用变量中停止一个非援用赋值操作,这个时分会直接履行copy内存的操作。
    以上面的例子来讲
    $a = 1;
    $b = &$a;
    $c = $b;
    在履行完前两行后,PHP中内存布局以下:
    
  

                               
登录/注册后可看大图
   
    在第三句,则会履行“援用下的变量分别”也就是真实的copy,终究内存布局以下图
    
  

                               
登录/注册后可看大图
   
    据此,根基上对PHP变量外部的一些道理对照清晰了,但还有一些需求注重点的:
    1、PHP变量的援用计数特征,关于数组一样也存在。但注重,关于key则不失效。(详细在前面章节会剖析到。)
    2、PHP变量中的对象对照特别,在PHP5以后,默许都是采取援用赋值的体例。详细完成可以参考Zend_objects.*系列代码。
    3、关于剖析PHP外部变量,保举采取xdebug_debug_zval,而不要采取内置的debug_zval_dump。由于PHP内置的debug_zval_dump函数一方面没法处置is_ref,并且采取了援用的体例来处置,从而招致看到了局会有曲解。
    利用技能结论
    据此可以得出剖析出很多结论:
    1、在PHP开辟中不保举采取援用。由于PHP外部对内存优化自己做了很多任务,援用不会带来太多优化。(但注重保举非强迫)
    2、在PHP中strlen是o(1)的。
说说这一个月左右的学习情况和心得吧!我个人认为,既然决定了去做一件事,那就要以认真的态度去对待!既然决定来学习了,那不管当初是抱着怎样的心态来到这个培训班的,都要让自己认真的投入到学习中。
飘灵儿 该用户已被删除
沙发
发表于 2015-2-4 02:22:26 | 只看该作者
刚开始安装php的时候,我图了个省事,把php的扩展全都打开啦(就是把php.ini 那一片 extension 前面的冒号全去掉啦),这样自然有好处,以后不用再需要什么功能再来打开。
老尸 该用户已被删除
板凳
发表于 2015-2-4 13:15:04 | 只看该作者
php是动态网站开发的优秀语言,在学习的时候万万不能冒进。在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理。
第二个灵魂 该用户已被删除
地板
发表于 2015-2-9 23:21:46 | 只看该作者
Apache不是非得用80或者8080端口的,我刚开始安得时候就是80端口老占用,就用了个 81端口,结果照常,就是输localhost的时候,应该输入为 localhost:81
admin 该用户已被删除
5#
发表于 2015-2-26 05:57:47 | 只看该作者
作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。
若天明 该用户已被删除
6#
发表于 2015-3-8 12:14:17 | 只看该作者
其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎
蒙在股里 该用户已被删除
7#
发表于 2015-3-9 20:58:03 | 只看该作者
如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了,
乐观 该用户已被删除
8#
发表于 2015-3-10 23:01:47 | 只看该作者
先学习php和mysql,还有css(html语言很简单)我认为现在的效果比以前的方法好。
深爱那片海 该用户已被删除
9#
发表于 2015-3-11 21:48:39 | 只看该作者
爱上php,他也会爱上你。
冷月葬花魂 该用户已被删除
10#
发表于 2015-3-15 16:58:14 | 只看该作者
建数据库表的时候,int型要输入长度的,其实是个摆设的输入几位都没影响的,只要大于4就行,囧。
变相怪杰 该用户已被删除
11#
发表于 2015-3-19 05:41:53 | 只看该作者
使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。
因胸联盟 该用户已被删除
12#
发表于 2015-3-27 08:08:14 | 只看该作者
环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。
再现理想 该用户已被删除
13#
发表于 2015-3-27 15:08:41 | 只看该作者
真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎,
山那边是海 该用户已被删除
14#
发表于 2015-4-4 09:55:30 | 只看该作者
学习php的目的往往是为了开发动态网站,phper就业的要求也涵盖了很多。我大致总结为:精通php和mysql
若相依 该用户已被删除
15#
发表于 2015-4-6 23:11:14 | 只看该作者
不禁又想起那些说php是草根语言的人,为什么认得差距这么大呢。
小魔女 该用户已被删除
16#
发表于 2015-4-13 15:03:11 | 只看该作者
使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。
爱飞 该用户已被删除
17#
发表于 2015-4-21 16:07:20 | 只看该作者
,熟悉html,能用div+css,还有javascript,优先考虑linux。我在开始学习的时候,就想把这些知识一起学习,我天真的认为同时学习能够互相呼应,因为知识是相通的。
愤怒的大鸟 该用户已被删除
18#
发表于 2015-4-25 02:45:11 | 只看该作者
我学习了一段时间后,我发现效果并不好(估计是我自身的问题)。因为一个人的精力总是有限的,同时学习这么多,会导致每个的学习时间都得不到保证。
透明 该用户已被删除
19#
发表于 2015-6-14 02:02:07 | 只看该作者
有时候汉字的空格也能导致页面出错,所以在写代码的时候,要输入空格最好用引文模式。
不帅 该用户已被删除
20#
发表于 2015-6-17 19:54:17 | 只看该作者
本人接触php时间不长,算是phper中的小菜鸟一只吧。由于刚开始学的时候没有名师指,碰过不少疙瘩,呗很多小问题卡过很久,白白浪费不少宝贵的时间,在次分享一些子的学习的心得。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 00:03

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表