良好的代码编写习惯
/**
* 去除字符中%
*
* @param $value
* @return mixed
*/
良好的编码习惯,包括良好的注释
Restful是一种设计风格而不是标准
PHP实现Restful风格的API
软件架构
系统架构设计中的be responsible for思想
表随业务走,直接在表里加字段,一个租房业务就一张表
重构
(1)单向依赖
(2)对数据分层的目的,就是使得每一层向下聚合,依赖,但是同级independent
解耦:
(1)对外提供接口,作为业务调用方,尽量少的知道接口的实现细节,尽量避免业务方改代码。
(2)提供接口不要暴露数据库的数据结构。
(3)对数据的转换,在接口内部做,让业务方感知不到。
底层物理存储改变怎么办?系统需要良好的拓展性
我们逻辑处理的其实是model,表名都可以改变,Model层不用冗余业务代码,View去干???这个有问题,若底层数据库迁移了,bll要修改大量代码
读取接口也抽象到model里面,接口名改变了,只需要改动一个地方
如何写好代码?
(1)面向对象的思想
(2)利用配置文件
做的比较灵活的就是,你想稍微修改得到一点其他的效果,不用修改你的代码,使用比较常用的配置文件来实现!
(3)能用静态方法尽量用静态方法,效率高
(4)代码中有硬编码
定义常量,不要硬编码
硬编码就是什么都在你的程序代码里面写死了,你想稍微修改一下效果,都得修改你的代码。
定义常量加上注释后别人就知道这个常量是干嘛用的
(5)用sprintf()函数连接字符串,比点号直接拼接效率高,单引号比双引号效率高
PHP单双引号的区别
用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会。
PHP引擎允许使用单引号和双引号来封装字符串变量,但是这个是有很大的差别的!使用双引号的字符串告诉PHP引擎首先去读取字符串内容,查找其中的变量,并改为变量对应的值。
一般来说字符串是没有变量的,所以使用双引号会导致性能不佳。最好是使用字符串连接而不是双引号字符串。
BAD:
$output = "This is a plain string";
GOOD:
$output = 'This is a plain string';
BAD:
$type = "mixed";
$output = "This is a $type string";
GOOD:
$type = 'mixed';
$output = 'This is a ' . $type .' string';
(6)$row['id']比$row[id]速度快7倍,建议养成数组键加引号的习惯
(7)不要随便就复制变量
有时候为了使PHP代码更加整洁,一些PHP新手(包括我)会把预定义好的变量复制到一个名字更简短的变量中,其实这样做的结果是增加了一倍的内存消耗,只会使程序更加慢。
试想一下,在下面的例子中,如果用户恶意插入512KB字节的文字到文本输入框中,这样就会导致1MB的内存被消耗!
BAD:
$description = $_POST['description'];
echo $description;
GOOD:
echo $_POST['description'];
php优化方法
http://www.open-open.com/lib/view/open1332904714233.html
php代码规范
phpstorm的code->inspect code
psr2规范
https://docs.opnsense.org/development/guidelines/psr2.html
php常用数组函数
array_wark和array_map区别
array_map() 返回用户自定义函数作用后的数组。
array_walk() 对数组中每个元素使用回调函数,返回bool值。
(1)array_wark
array_walk($data, function (&$value) {
/** 朝向 */
$value['toward'] = CommonDictModel::getAliasByNameAndValue(self::ORIENTATION,
$value['orientation']);
/** 物业类型 */
$value['property_name'] = CommonDictModel::getAliasByNameAndValue(self::PROPERTY,
$value['property']);
});
(2)array_map
$array = array('AAA', 'bbb');
$map_array = array_map('strtolower', $array);
print_r($map_array);
print_r($array);
array_walk和array_map区别
array_map() 返回用户自定义函数作用后的数组。
array_walk() 对数组中每个元素使用回调函数,返回bool值。
array_values()返回数组的所有值(非键名)
array_flip()反转数组中所有的键以及它们关联的值
array_intersect() 函数用于比较两个(或更多个)数组的键值,并返回交集
array_key_exists()判断数组键值存在不存在
array_diff()可用一个或任意多个数组与第一个数组进行比较,返回差集
array_push()将一个或多个单元压入数组的末尾(入栈)
array_merge() php里面貌似这两种方法都可以合并数组,我就发现了一点,就是array_merge是后面覆盖前面,而+是前面覆盖后面,比如下面的代码
$a = array('a' => 1, 'b' => 2, 'c' => 3);
$b = array('b' => 5, 'c' => 6, 'd' => 7);
print_r(array_merge($a, $b));
print_r($a + $b);
Array
(
[a] => 1
[b] => 5
[c] => 6
[d] => 7
)
Array
(
[a] => 1
[b] => 2
[c] => 3
[d] => 7
)
array_combine() 函数通过合并两个数组来创建一个新数组,其中的一个数组是键名,另一个数组的值为键值
array_slice() 函数在数组中根据条件取出一段值,并返回
laravel自带:
array_get
php5.2新增对json的处理,json_encode()和json_decode()
php5.3新增命名空间和闭包
php5.4数组简写形式和Traits
PHP5.5:yield, list() 用于 foreach, 细节修改
list() 用于 foreach
可以用 list() 在 foreach 中解析嵌套的数组:
$array = [
[1, 2, 3],
[4, 5, 6],
];
foreach ($array as list($a, $b, $c))
echo "{$a} {$b} {$c}\n";
PHP5.6: 常量增强,可变函数参数,命名空间增强 定义常量时允许使用之前定义的常量进行计算命名空间支持常量和函数
php的闭包(Closure),是PHP5.3引入的。
在编程领域我们可以通俗的说:子函数可以使用父函数中的局部变量,这种行为就叫做闭包。
匿名函数(Anonymous functions),也叫闭包函数(closures),允许临时创建一个没有指定名称的函数。
Route::get('/', 参数),这个参数的位置你写了function () {}之类的,而不是一个普通变量,这就是闭包,function () {} 没有名字,这就是匿名函数。
php闭包作用:
减少foreach的循环的代码
减少函数的参数
延迟绑定
Traits
Trait的优先级
从基类继承的成员被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。
从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。
<?php
class Base {
public function sayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public function sayHello() {
parent::sayHello();
echo 'World!';
}
}
class MyHelloWorld extends Base {
use SayWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
php不支持多态(方法名一样,参数不一样(个数或类型不一样),即重载),支持方法重写
PHP 将所有以 __(两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,除了上述魔术方法,建议不要以 __ 为前缀。
__call()对象调用某个方法。若方法不存在,这调用__call 这个方法
读取一个对象属性,如果对象属性是私有的,会调用__get()
给一个对象属性赋值时如果属性是私有的,会调用__set()
PHP中实现函数重载
<?php
class A
{
function __call ($name, $args)
{
if($name=='f')
{
$i=count($args);
if (method_exists($this,$f='f'.$i)) {
call_user_func_array(array($this,$f),$args);
}
}
}
function f1($a1)
{
echo "1个参数".$a1."<br/>";
}
function f2($a1,$a2)
{
echo "2个参数".$a1.",".$a2."<br/>";
}
function f3($a1,$a2,$a3)
{
echo "3个参数".$a1.",".$a2.",".$a3."<br/>";
}
}
(new A)->f('a');
(new A)->f('a','b');
(new A)->f('a','b','c');
?>
输出如下:
1个参数a
2个参数a,b
3个参数a,b,c
php中abstract与interface的区别
1、抽象类需要继承,用extends,而接口需要实现,用implements;
2、一个类可以实现多个接口,但只能继承一个抽象类
3、接口中每个方法都只有声明而没有实现,其中的每个方法实现类必须要实现;而抽象类中只需要实现抽象方法,其它方法可以选择性的实现;
4、接口中只能声明public的方法,不能声明private和protected的方法,不能对方法进行实现,也不能声明实例变量;但是抽象类中可以
final class MyClass{//此类将不允许被继承
final function fun1(){......}//此方法将不允许被重写
}