PHP解惑(一)
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解惑(一)的更多相关文章
- [C#解惑] #2 对象的初始化顺序
谜题 在上一篇C#解惑中,我们提到了对象的初始化顺序.当我们创建一个子类的实例时,总是会先执行基类的构造函数,然后再执行子类的构造函数.那么实例字段是什么时候初始化的呢?静态构造函数和静态字段呢?今天 ...
- [C#解惑] #1 在构造函数内调用虚方法
谜题 在C#中,用virtual关键字修饰的方法(属性.事件)称为虚方法(属性.事件),表示该方法可以由派生类重写(override).虚方法是.NET中的重要概念,可以说在某种程度上,虚方法使得多态 ...
- Python 包管理工具解惑
Python 包管理工具解惑 本文链接:http://zengrong.net/post/2169.htm python packaging 一.困惑 作为一个 Python 初学者,我在包管理上感到 ...
- 《浅谈磁盘控制器驱动》,磁盘控制器驱动答疑解惑![2012.1.29完结]by skyfree
<浅谈磁盘控制器驱动>,磁盘控制器驱动答疑解惑![2012.1.29完结] https://www.itiankong.net/thread-178655-1-1.html Skyfre ...
- SAE上传web应用(包括使用数据库)教程详解及问题解惑
转自:http://blog.csdn.net/baiyuliang2013/article/details/24725995 SAE上传web应用(包括使用数据库)教程详解及问题解惑: 最近由于工作 ...
- 【解惑】Java动态绑定机制的内幕
在Java方法调用的过程中,JVM是如何知道调用的是哪个类的方法源代码? 这里面到底有什么内幕呢? 这篇文章我们就将揭露JVM方法调用的静态(static binding) 和动态绑定机制(auto ...
- word wrap 解惑
源起 我们经常需要“修复”一个老生常谈的“bug”,那就是文本的自动换行问题.在专业术语上,这种期望得到的渲染现象被称作“word wrap”,即文本处理器有能力把超出页边的整个词自动传到下一行. 在 ...
- (译)iOS Code Signing: 解惑
子龙山人 Learning,Sharing,Improving! (译)iOS Code Signing: 解惑 免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切 ...
- C#中的 ref 传进出的到底是什么 解惑篇
今天在浏览博文时,看到这篇文章:C#中的ref 传进出的到底是什么 ? 在传对象时使用ref的疑问 另附言: 本文写于早上,就在想发布的那瞬间,靠,公司断网了,原来修改的部分丢失了. 网一断就是一天了 ...
- 【解惑】深入jar包:从jar包中读取资源文件
[解惑]深入jar包:从jar包中读取资源文件 http://hxraid.iteye.com/blog/483115 TransferData组件的spring配置文件路径:/D:/develop/ ...
随机推荐
- SVN常用命令说明(转载)
转自:http://www.blogjava.net/jasmine214--love/archive/2011/01/12/342839.html /** * 转载请注明作者longdick htt ...
- maven配置文件注意事项
1:安装完成后在C:\Users\Administrator\.m2有一个文件settings.xml需要修改一下配置 2:设置maven从网上下载的jar包.(时间长会很大).我设置它保存我的电脑位 ...
- 51nod 1244 莫比乌斯函数之和 【莫比乌斯函数+杜教筛】
和bzoj 3944比较像,但是时间卡的更死 设\( f(n)=\sum_{d|n}\mu(d) g(n)=\sum_{i=1}^{n}f(i) s(n)=\sum_{i=1}^{n}\mu(i) \ ...
- 洛谷 P3708 koishi的数学题
找规律发现\( f[i]=f[i-1]+n-\sum_{i的因数和} \) 一A了深(sh)蓝(ui)题的我被找规律绿题卡死 记得开long long #include<iostream> ...
- [Usaco2009 Feb]庙会捷运Fair Shuttle
Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1& ...
- [POI2008]海报PLA
Description N个矩形,排成一排. 现在希望用尽量少的矩形海报Cover住它们. Input 第一行给出数字N,代表有N个矩形.N在[1,250000] 下面N行,每行给出矩形的长与宽.其值 ...
- 树上最长链 Farthest Nodes in a Tree LightOJ - 1094 && [ZJOI2007]捉迷藏 && 最长链
树上最远点对(树的直径) 做法1:树形dp 最长路一定是经过树上的某一个节点的. 因此: an1[i],an2[i]分别表示一个点向下的最长链和次长链,次长链不存在就设为0:这两者很容易求 an3[i ...
- 二分查找/暴力 Codeforces Round #166 (Div. 2) B. Prime Matrix
题目传送门 /* 二分查找/暴力:先埃氏筛选预处理,然后暴力对于每一行每一列的不是素数的二分查找最近的素数,更新最小值 */ #include <cstdio> #include < ...
- 如何隐藏electron窗体的菜单栏
electron中默认带有顶部菜单栏,有时候我们的应用不需要. 再main.js文件中设置 const electron = require('electron') const path = requ ...
- js ajax 数组类型参数传递
若一个请求中包含多个值,如:(test.action?tid=1&tid=2&tid=3),参数都是同一个,只是指定多个值,这样请求时后台会发生解析错误,应先使用 tradititon ...