周五一朋友来着一段代码来问我,说他看不懂这段代码,觉得这段代码有问题,代码类似:
代码如下 | 复制代码 |
$array1 = array(1, 2); $result = empty($array1) == 3 ? $array1 : $array2; |
我一看应该是运算符优先级的问题。
按理说,这些运算符优先级的问题是不应该让它出现在项目代码中的,只能让它在面试问题中,程序员应该在书写代码过程中使用括号来避免这种不确定问题的出现。项目中的代码应该是那种我们一看就知道结果的,而不是需要我们费劲脑子才能知道结果的。这种优先级代码的结果有时候并不是我们相信的那样,看看下面的例子:
代码如下 | 复制代码 |
<?php |
上面代码也许你会认为是:
代码如下 | 复制代码 |
<?php if ($a = (100 && $b) = 200) { var_dump($a, $b); } |
但是实际上不是这样的,实际结果是:
代码如下 | 复制代码 |
<?php if ($a = (100 && $b = 200)) { var_dump($a, $b); } |
至于为什么会这样?那是因为PHP并不完全遵守优先级的定义,PHP手册上中有说明
Note: Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a.
代码:
代码1:
代码如下 | 复制代码 |
<?php |
这种代码在实际项目中是不应该出现的,都应该用下面的代码替换:
代码如下 | 复制代码 |
$z = ($y OR $x); $z = ($y || $x); |
语法:
要指定一个布尔值,使用关键字 TRUE 或 FALSE 。两个都不区分大小写。
代码如下 | 复制代码 |
<?php $foo = True ; // assign the value TRUE to $foo ?> |
通常运算符所返回的 boolean 值结果会被传递给控制流程。
代码如下 | 复制代码 |
<?php // 这样做是不必要的... // ...因为可以使用下面这种简单的方式: |
转换为布尔值
要明确地将一个值转换成 boolean ,用 (bool) 或者 (boolean) 来强制转换。但是很多情况下不需要用强制转换,因为当运算符,函数或者流程控制结构需要一个 boolean 参数时,该值会被自动转换。
当转换为 boolean 时,以下值被认为是 FALSE :
1.布尔值 FALSE 本身
2.整型值 0(零)
3.浮点型值 0.0(零)
4.空字符串,以及字符串 "0"
5.不包括任何元素的数组
6.不包括任何成员变量的对象(仅 PHP 4.0 适用)
7.特殊类型 NULL(包括尚未赋值的变量)
8.从空标记生成的 SimpleXML 对象
所有其它值都被认为是 TRUE (包括任何资源)。
注意:1 和其它非零值(不论正负)一样,被认为是 TRUE !
代码如下 | 复制代码 |
<?php var_dump ((bool) "" ); // bool(false) var_dump ((bool) 1 ); // bool(true) var_dump ((bool) - 2 ); // bool(true) var_dump ((bool) "foo" ); // bool(true) var_dump ((bool) 2.3e5 ); // bool(true) var_dump ((bool) array( 12 )); // bool(true) var_dump ((bool) array()); // bool(false) var_dump ((bool) "false" ); // bool(true) ?> |
单例模式的特点:
1、构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化;
2、拥有一个保存类的实例的静态成员变量
3、拥有一个访问这个实例的公共的静态方法(常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到类是否已经被实例化)
另外,需要创建__clone()方法防止对象被复制(克隆)
DEMO(链接数据库):
代码如下 | 复制代码 |
/* 例子:数据库连接职责的集中控制 */ |
PHP使用header函数设置HTTP头的示例方法
代码如下 | 复制代码 |
//定义编码 //显示登陆对话框 |
php中static静态变量的使用方法详解
php中的变量作用范围的另一个重要特性就是静态变量(static 变量)。静态变量仅在局部函数域中存在且只被初始化一次,当程序执行离开此作用域时,其值不会消失,会使用上次执行的结果。
编程实例:
代码如下 | 复制代码 |
function test() { static $aa = 0; return $aa++; } $aa = "1000"; echo $aa; echo test(); echo test(); echo $aa; |
本函数每调用test()都会输出 $aa的值并加一。
上文代码运行输出:
1000
0
1
1000
静态变量也提供了一种处理递归函数的方法。递归函数是一种自己调用自己的方法。写递归函数时要小心,因为可能会无穷递归下去,没有出口.务必确保 有方法来中止递归。
一维数组按照元素或者键值分组变为二维数组
有时候查询数据库记录后会对数据库查询结果进行分组,即将一维数组变为二维数组,方便调用使用(通常是json)
代码如下 | 复制代码 |
$arr = array( Array [f2] => Array ) |
PHP的静态绑定和动态绑定(private/public)
子类Foo的对象调用了test()方法,test()方法调用了$this->testPrivate();这个$this此时应该是子类的引用,按理说应该调用子类的testPrivate()方法,实际上却调用了父类的testPrivate()方法
代码如下 | 复制代码 |
class Bar public function testPublic() { class Foo extends Bar $myFoo = new Foo(); |
这是PHP的动态绑定和静态绑定的一种情况。
public是动态绑定,在编译期不绑定,所以在运行期调用父类的test()方法的时候,会解析为子类的public方法。
而private是私有的,不会继承到子类,在编译期就绑定了,是一种“静态”的绑定(类似5.3后的self)。
与这个相关的是LSB,静态延迟绑定,PHP5.3因为有了这个特性之后,使PHP的OOP得到加强
public: 可以被继承,也可以被外部调用。
private: 不可以被继承,也不可以被外部调用。
protected: 可以被继承,但不能被外部调用。
PHP三种运行方式mod_php5/cgi/fast-cgi
a.通过HTTPServer内置的模块来实现,
例如Apache的mod_php5,类似的Apache内置的mod_perl可以对perl支持;
b.通过CGI来实现
这个就好比之前perl的CGI,该种方式的缺点是性能差,因为每次服务器遇到这些脚本都需要重新启动脚本解析器来执行脚本然后将结果返回给服务器;另一方面就是不太安全;该方面几乎很少使用了。
c.最新出现一种叫做FastCGI。
所谓FastCGI就是对CGI的改进。它一般采用C/S结构,一般脚本处理器会启动一个或者多个daemon进 程,每次HTTPServer遇到脚本的时候,直接交付给FastCGI的进程来执行,然后将得到的结果(通常为html)返回给浏览器。
该种方法的问题存在一个小问题是当遇到大流量的频繁请求的话,脚本处理器的daemon进程可能会超负荷从而变得很慢,甚至发生内存泄漏;
但是比较起Apache的内置模块的方式的优点是由于Server和脚本解析器完全分开各负其责,因此服务器不再臃肿,可以专心地进行静态文件响 应或者将动态脚本解析器的结果返回给用户客户端。所以比较起Apache的内置模块方式,有时候性能要提高很多。有人测试可能会达到 Apache+mod_php的5~10倍。
三种常用模式:
Apache+mod_php5;
lightppd+spawn-fcgi;
nginx+PHP-FPM
我们可以使用到生产环境中的:
0) 如果不是server cluster的话:
可以使用以上任一种,不过有各种测试表明nginx+PHP-FPM性能优越,但是Apache+mod_php5很经典模块多,比如对.htaccess等的支持。
如果构建server cluster的话:
1) nginx作为反向代理服务器,后台多台Apache+mod_php5。
nginx处理静态文件,及对php并发请求对后台多台app server的负载均衡;
2) nginx作为反向代理器,后台多台PHP-FPM
nginx处理静态文件及将php并发请求发送到后台php-fpm来解析;
三种变量命名规则(匈牙利法,小驼峰法,大驼峰法)
1. 匈牙利命名:
•开头字母用变量类型的缩写,其余部分用变量的英文或英文的缩写,要求单词第一个字母大写。
•For example: long lsum = 0;"l"是类型的缩写;
2. 小驼峰式:(little camel-case)
•第一个单词首字母小写,后面其他单词首字母大写。
•For example: string firstName = string.Empty;
3. 大驼峰式:(big camel-case)
•每个单词的第一个字母都大写;
•For example:string FirstName = string.Empty;
解决 Json 中文转码问题
代码如下 | 复制代码 |
//代码 $data = array( 'status'=>'1', 'method'=>'登陆', 'message'=>'成功', ); echo json_encode($data); //显示 {"status":"1","method":"u767bu9646","message":"u6210u529f"} |
json_encode 只能接受utf-8格式的数据,最终的json中中文部分被替换为unicode编码。我们要解决的就是将对象转换为json并保证对象内部的中文在json中仍然是以正常的中文出现。
先将类中的中文字段进行url编码(urlencode),然后再对对象进行json编码(jsonencode),最后url解码(urldecode)json,即最终的json,里面的中文依旧是那个中文。
代码如下 | 复制代码 |
//代码 foreach ( $data as $key => $value ) { $newData[$key] = urlencode ( $value ); } echo urldecode(json_encode($newData)); //显示 {"status":"1","method":"登陆","message":"成功"} |
Ajax跨域请求CORS错误
编写Json api供其他站点查询调用的时候有时候使用ajax方式获取,此时,可能ACAO的设置,那么将发生CROS错误。
//报错
XMLHttpRequest cannot load http://www.111cn.net . No 'Access-Control-Allow-Origin' header is present on the requested resource.
//解决办法
代码如下 | 复制代码 |
header('Access-Control-Allow-Origin: *'); //hooks配置 //插件编写
if(in_array($class.'/'.$method,$ssl)){ //config 配置需要使用https的 class method |
//强制不使用ssl
最简单的全局变量函数就是$_SERVER[\'DOCUMENT_ROOT\']与$HTTP_SERVER_VARS[\'DOCUMENT_ROOT\']了,但是我们要调用文件的话就无法这样实现了,具体如何写呢,下面我们一起来看看。用php开发网站的时候有时候经常要用到当前网站的根目录, 比如包含一个文件:
代码如下 | 复制代码 |
include_once("./includefile.php"); |
那么要想写根目录的形式应该怎么写呢?
这时候通常用 dirname(__FILE__) 这个函数, 意思是获取当前文件所在的根目录,
那么这个php语句就是这样的了:
代码如下 | 复制代码 |
include_once(dirname(__FILE__) ."/includefile.php"); |
将下面的代码放在网站根目录下的一个文件中,以便在其它文件中引用。
路径方式:
代码如下 | 复制代码 |
define('BASE_PATH',str_replace('\\','/',realpath(dirname(__FILE__).'/'))."/"); echo BASE_PATH; |
输出结果:E:/www.111cn.net /
url方式:
代码如下 | 复制代码 |
$PHP_SELF=$_SERVER['PHP_SELF']; $url='http://'.$_SERVER['HTTP_HOST'].substr($PHP_SELF,0,strrpos($PHP_SELF,'/')+1); echo $url; |
//注意大小写问题, linux下对大小写敏感, 要养成认真对待大小写的习惯, 以免win主机换到linux下不兼容的问题