PHP给人的印象是入门简单的语言。当你的技术能力达到一定阶段时,会发现情况并非如此。

PHP采用"极简主义",就是以入门容易为准则设计的,在十几年的持续发展历程中,它早已成为一个开源领域的语言且具备现代语言特性的平台之一,在Web开发领域,我们相信PHP就是"世界上最好的语言"。

人无完人,语言也一样。天下事物都需要花大量经理去研究实践,深入下去不是易事,了解越多越敬畏。况且Web开发又是个严谨创意,如不能通透理解隐藏在后面的深层机制,就有可能损害应用的性能,导致低级错误的发生。

1、省略结束标签的便利性

对于PHP编译器来说,脚本的结束标签"?>"是可选的,在写程序时你可以忽略它。

省略结束标签适合纯PHP文件,如果是PHP与HTML混合开发,则不可省略。

2、empty、isset、is_null的区别

变量在所有计算机语言中均有提供,它用来保存数值、文本、对象等内容。我们可以把变量看作一个有名称的桶,里面放着一个值,这个值可以是数字、字符串或对象,以及包含你想到的任何合法的内容。

PHP提供了3个用于测试变量值的函数,分别是:isset()、empty()和is_null()。这几个函数均返回布尔值,有时使用不当会造成意想不到的结果,需要详细说明。

比如,用isset()和empty()返回的结果是相反的,但有时却并非一致如此。

<?php
//isset()用来检测一个变量是否已声明且值不为NULL,换句话说,只能在变量值不是NULL时返回真值。
//empty()用来检测一个变量是否为空,也就是说有如下情况时返回真值:变量是一个空字符串,flase,空数组[array()],NULL,0,'',以及被unset删除后的变量。
//is_null()用来判断变量是否是NULL值,即返回真值的条件仅为变量是NULL时。
//is_null()是isset()函数的反函数,区别是isset()函数可以应用到未知变量,但is_null()只能针对已声明的变量。

$var='';//空字符串
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(true)
var_dump(is_null($var));//bool(false)

echo '<hr />';
$var=' ';//空格
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(false)
var_dump(is_null($var));//bool(false)

echo '<hr />';
$var=false;
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(true)
var_dump(is_null($var));//bool(false)

echo '<hr />';
$var=true;
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(false)
var_dump(is_null($var));//bool(false)

echo '<hr />';
$var=array();//空数组
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(true)
var_dump(is_null($var));//bool(false)

echo '<hr />';
$var=NULL;//空数组
var_dump(isset($var));//bool(false)
var_dump(empty($var));//bool(true)
var_dump(is_null($var));//bool(true)

echo '<hr />';
$var="0";//空数组
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(true)
var_dump(is_null($var));//bool(false)

echo '<hr />';
$var=0;//空数组
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(true)
var_dump(is_null($var));//bool(false)

echo '<hr />';
$var=0.0;//空数组
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(true)
var_dump(is_null($var));//bool(false)

echo '<hr />';
//var $var;//JavaScript使用var声明变量,其实在PHP中,根本不需要使用var声明的,但是当一个变量作为一个类的成员变量时,使用var还是没有问题的。
        //但是,如果在外部使用var就报错:Parse error: syntax error, unexpected T_VAR in...
        //在PHP中,只要使用"$"符号其实就表示这个字符后面的是一个PHP变量。
$var;
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(true)
var_dump(is_null($var));//bool(false)

echo '<hr />';
$var='\0';//空字节
var_dump(isset($var));//bool(true)
var_dump(empty($var));//bool(false)
var_dump(is_null($var));//bool(false)
?>

3、布尔值的正确打开方式

关于布尔值,在PHP中可以这么来写:

<?php  $flag=True;  ?>

<?php $flag=TRUE; ?>

<?php $flag=true; ?>

这3段代码都可以正常运行,但是,哪个最好?哪个是正确的?

在PHP中,常量规定为大写,第二行代码显然是正确的。

4、变量作用域

在PHP中定义一个变量后,在脚本的任意为止都可以存取访问,这被成为全局变量,而定义在函数或类的方法中的变量只可以在函数内部访问,这叫做局部变量。

使用局部变量可以使源代码易于管理,试想如果所有的变量都是全局的,任何位置都可访问、修改它的内容,如果变量重名就可能发生"污染"。

通过声明局部变量来限制一个变量的存取范围,可以让代码模块化,易调试,让应用运行更健壮。

PHP允许函数内部可访问外部全局变量,只需在函数中使用global关键字即可。

5、多维数组排序

使用PHP开发应用,几乎就是一致跟数组打交道。PHP数组的强大和灵活性嫩够解决大部分应用的问题。

在数组编程中,常用的有sort()、ksort()等相关函数,使用它们就可以很方便地处理一维数组,比如按键值降序和升序排列。

<?php
//定义一个简单的二维数组
$a=array(
    array("sky","blue"),
    array("apple","red"),
    array("tree","green")
    );

//为了给多维数组进行排序,需要自定义排序函数,然后再调用sort()、usort()、ksort()这些函数,让这些函数使用自定义函数
/**my_compare()函数
*@param $a
*@param $b
*@return int
@功能:接受两个参数,如果返回值为负数或FALSE意味着第一个参数应该排在第二个参数之前
                     如果返回整数或TRUE表示第二个参数应该排在前面
                     如果值为0表示两个参数相等
*/
function my_compare($a,$b){
    if($a[1]<$b[1]){
        return -1;
    }else if($a[1]==$b[1]){
        return 0;
    }else{
        return 1;
    }
}

/**
*@param $a,数组名称
*@param my_compare 自定义函数
*功能:使用自定义比较函数对数组中的值进行排序并保持索引关联
*/
//排序
uasort($a,'my_compare');

//输出结果
foreach($a as $elem){
    echo "$elem[0]:$elem[1]<br />";
}
/*
    sky:blue
    tree:green
    apple:red
*/

6、超级全局数组

超级全局数组是由PHP内置的,无须开发者重新定义。

PHP执行时会自动将当前脚本需要收集的数据分类保存再这些超级全局数组中,这些数组有十多个分类,每个数组保存的内容和功能不同。

名称 功能
$_GET[] 取得用GET方法提交的表单内容,数组键和值分别对应元素名和值
$_POST[] 取得用POST方法提交的表单内容,数组键和值分别对应元素名和值
$_COOKIE[] 取得或设置当前站点的Cookie
$_SESSION[] 取得当前用户访问的会话,以数组形式体现,如sessionid及自定义session数据
$_ENV[] 当前PHP服务器的环境变量
$_SERVER[] 当前PHP运行环境的服务器变量
$_FILES[] 用户上传文件时提交到当前脚本参数
$_REQURES[] 包含当前脚本提交的所有请求,它包含了$_GET、$_POST、$_COOKIE、$_SESSION这些超级全局数组的全部内容
$GLOBALS[]  该超级变量数组包含正在执行脚本时所有超级全局数组的内容

$GLOBALS超级全局数组可以让我们在函数里访问全局变量。

7、global关键字与global数组的区别

  $GLOBALS[‘var’]是外部的全局变量本身,glboal $var是外部$var的同名引用或者指针

  PHP的"全局"不是指整个网站,而是应用于当前页面,包括include或require的全部文件。

<?php
$var1 =1;
function test1(){
    unset($GLOBALS['var1']);
}
test1();
echo $var1;    //Notice: Undefined variable: var1 in
            //因为$var1变量被删除,所以没有内容显示出来。

$var2=1;
function test2(){
    global $var2;
    unsert($var2);
}
test2();
echo $var1;    //输出1
            //因为删除的只是个别名引用,其本身的值并没有任何更改。
            //$var2 等价于$GLOBALS['var2']指向的是同一个变量

8、活用静态变量

在PHP脚本函数内部创建的局部变量,执行时时存在的,当执行完毕后会在内存里立即删除,再次运行函数时会重新创建。

这样的优点是:确保函数每次执行是完整独立的,以免混乱。

但有时会想在函数调用时保存上次局部变量执行的结果,以便下次执行时使用,这时就可以用静态变量来实现。

未使用静态变量

<?php
//自定义一个函数,功能是返回函数被调用的次数
function createWidget(){
    $numWidgets =0;
    return ++$numWidgets;
}
echo "Create some widgets...<br />";
echo createWidget()."created so far.<br />";
echo createWidget()."created so far.<br />";
echo createWidget()."created so far.<br />";

/*结果如下:
    Create some widgets...
    1created so far.
    1created so far.
    1created so far.
*/
?>

我们三次调用createWidget()函数,每一次函数被调用时,内部的$numWidgets变量都是从1开始,而不是每次累加,没有达到想要的预期结果。

而使用静态变量,就可以在每次函数调用时使用它上次运算的值。下面修改一下代码,将局部变量声明为静态变量。

使用静态变量

<?php
//自定义一个函数,功能是返回函数被调用的次数
function createWidget(){
    static $numWidgets =0;
    return ++$numWidgets;
}
echo "Create some widgets...<br />";
echo createWidget()."created so far.<br />";
echo createWidget()."created so far.<br />";
echo createWidget()."created so far.<br />";

/*结果如下:
    Create some widgets...
    1created so far.
    1created so far.
    1created so far.
*/
?>

这时,静态变量在函数调用时,保存了上次运行的值。当脚本运行完毕退出时,静态变量也会销毁,这一点和全局、局部变量特性相同。

PHP解惑(一)的更多相关文章

  1. [C#解惑] #2 对象的初始化顺序

    谜题 在上一篇C#解惑中,我们提到了对象的初始化顺序.当我们创建一个子类的实例时,总是会先执行基类的构造函数,然后再执行子类的构造函数.那么实例字段是什么时候初始化的呢?静态构造函数和静态字段呢?今天 ...

  2. [C#解惑] #1 在构造函数内调用虚方法

    谜题 在C#中,用virtual关键字修饰的方法(属性.事件)称为虚方法(属性.事件),表示该方法可以由派生类重写(override).虚方法是.NET中的重要概念,可以说在某种程度上,虚方法使得多态 ...

  3. Python 包管理工具解惑

    Python 包管理工具解惑 本文链接:http://zengrong.net/post/2169.htm python packaging 一.困惑 作为一个 Python 初学者,我在包管理上感到 ...

  4. 《浅谈磁盘控制器驱动》,磁盘控制器驱动答疑解惑![2012.1.29完结]by skyfree

    <浅谈磁盘控制器驱动>,磁盘控制器驱动答疑解惑![2012.1.29完结]  https://www.itiankong.net/thread-178655-1-1.html Skyfre ...

  5. SAE上传web应用(包括使用数据库)教程详解及问题解惑

    转自:http://blog.csdn.net/baiyuliang2013/article/details/24725995 SAE上传web应用(包括使用数据库)教程详解及问题解惑: 最近由于工作 ...

  6. 【解惑】Java动态绑定机制的内幕

    在Java方法调用的过程中,JVM是如何知道调用的是哪个类的方法源代码? 这里面到底有什么内幕呢? 这篇文章我们就将揭露JVM方法调用的静态(static binding) 和动态绑定机制(auto ...

  7. word wrap 解惑

    源起 我们经常需要“修复”一个老生常谈的“bug”,那就是文本的自动换行问题.在专业术语上,这种期望得到的渲染现象被称作“word wrap”,即文本处理器有能力把超出页边的整个词自动传到下一行. 在 ...

  8. (译)iOS Code Signing: 解惑

    子龙山人 Learning,Sharing,Improving! (译)iOS Code Signing: 解惑 免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切 ...

  9. C#中的 ref 传进出的到底是什么 解惑篇

    今天在浏览博文时,看到这篇文章:C#中的ref 传进出的到底是什么 ? 在传对象时使用ref的疑问 另附言: 本文写于早上,就在想发布的那瞬间,靠,公司断网了,原来修改的部分丢失了. 网一断就是一天了 ...

  10. 【解惑】深入jar包:从jar包中读取资源文件

    [解惑]深入jar包:从jar包中读取资源文件 http://hxraid.iteye.com/blog/483115 TransferData组件的spring配置文件路径:/D:/develop/ ...

随机推荐

  1. 微信公众平台——基础配置——服务器配置:PHP版

    在自己的服务器上新建一个空白php文件,输入以下任一版本的代码,如下: 版本一: <?php $token = "dige1994"; $signature = $_GET[ ...

  2. 【性能测试】服务器资源监测工具sar安装

    [root@yyy ~]# sar Cannot open /var/log/sa/sa19: No such file or directory 在Linux系统中,运行sar命令,发现无法执行: ...

  3. Linux 常用命令二 pwd cd

    一.pwd命令 显示整个路径名: wang@wang:~$ pwd /home/wang 二.cd命令 切换到其他路径(相对路径方式): wang@wang:~$ cd workpalce/ wang ...

  4. bzoj 1296: [SCOI2009]粉刷匠【dp+背包dp】

    参考:http://hzwer.com/3099.html 神题神题 其实只要知道思路就有点都不难-- 先对每一行dp,设g[i][j]为这行前i个格子粉刷了k次最大粉刷正确数,随便n^3一下就行 设 ...

  5. 洛谷 P4012 深海机器人问题 【最大费用最大流】

    和火星那个有点像,但是这个价值直接在路径上,不用拆点,对于每条价值为w的边(i,j),连接(i,j,1,w)(i,j,inf,0),表示价值只能取一次,然后连接源点和所有出发点(s,i,k,0),所有 ...

  6. 「vijos」lxhgww的奇思妙想(长链剖分)

    传送门 长链剖分的板子(又是乱搞优化暴力) 对于每一个点,我们定义它深度最深的子节点为它的重儿子(为什么不叫长儿子……),他们之间的连边为重边 然后长链剖分有几个性质 1.总链长为$O(n)$ 2.一 ...

  7. 使用vmware12安装Ubuntu 遇到的两个问题和解决

    1.need the x86-64 cpu,but only detected the xxx cpu. 这是因为bios中的virtual function 是 disabled,改为enabled ...

  8. [PKUWC2018]猎人杀

    题解 感觉是一道神题,想不出来 问最后\(1\)号猎人存活的概率 发现根本没法记录状态 每次转移的分母也都不一样 可以考虑这样一件事情: 如果一个人被打中了 那么不急于从所有人中将ta删除,而是给ta ...

  9. 线程池机制使nginx性能提高9倍

    原文标题:Thread Pools in NGINX Boost Performance 9x! 原文官方地址:https://www.nginx.com/blog/thread-pools-boos ...

  10. U9249 【模板】BSGS

    题目描述 给定a,b,p,求最小的非负整数x 满足a^x≡b(mod p) 若无解 请输出“orz” 输入输出格式 输入格式: 三个整数,分别为a,b,p 输出格式: 满足条件的非负整数x 输入输出样 ...