前言
php7特性,面向对象、提高算法等。
感觉学习进入平台期,个人的一些理解梳理。
大神镇楼:
大神:鸟哥 [风雪之隅][1]
大神:韩天峰 [rango][2]
1.php部分
a.php7对php5新特性
(1).null合并运算符(??)
$param = $_GET['param'] ?? 1;//1
(2).define() 定义常量数组
(3).组合比较符(<=>)
echo "a" <=> "a"; // 0 => 成立顺序对应-1.0.1
(4).变量类型声明两种模式: 强制(默认)和严格模式
declare(strict_types=1);//值为1代表为严格校验的模式
(5).返回值类型声明
(6).PHP7 错误处理
PHP7 改变了大多数错误的报告方式,现在大多数错误被作为 Error 异常抛出。这种 Error 异常可以像普通异常一样被 try / catch 块所捕获。
(7)打开配置项的opcache,php7.3.6默认:
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.enable_cli=1
b.面向对象编程
参考laravel学院《现代PHP/新特性》
(1).善用接口(定义处extends),分离实现细节;
(2).使用trait(特性:内部use),追加属性、方法;
(3).闭包的调用,调试;
(4).迭代Iterator/yield使用。
c.实用算法相关
(1).循环调用=>预约变现:使用生成器(yield)
function makeRange($length) {
for ($i=0; $i<$length; $i++) {
yield $i;
}
}
foreach (makeRange(1000000) as $i) {
echo $i . PHP_EOL;
}
yield让步,主动让出cpu执行权限,无法取回,等待next主动调用,参考《PHP yield 分析,以及协程的实现,超详细版(上)》。
(2).迭代树循环=>提纲挈领:使用&地址引用
function genTree(array $items,string $id='gcid',string $pid='parentgcid',string $son='children') array {
$tree = array(); //格式化的树
$tmpMap = array(); //临时扁平数据
//全部加载到内存,不用迭代器
foreach ($items as $item) {
$tmpMap[$item[$id]] = $item;
}
foreach ($items as $item) {
if (isset($tmpMap[$item[$pid]])) {
//把父子结构转换引用成地址,准备据完成后,输出时即是所需数据
$tmpMap[$item[$pid]][$son][] = &$tmpMap[$item[$id]];
} else {
$tree[] = &$tmpMap[$item[$id]];
}
}
return $tree;
}
2.概念原理部分
a.epool进程(linux)I/O复用
[nginx运行模型]
epoll提供了三个函数,epoll_create,epoll_ctl和epoll_wait,epoll_create是创建一个epoll句柄;epoll_ctl是注册要监听的事件类型;epoll_wait则是等待事件的产生。
I/O多路复用就是通过一种机制,一个进程可以监视多个描述符(socket),一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
b.Raft分布式一致性协议
[redis集群使用]
借鉴了美国总统大选的策略,采用精英领导全局的方案,整个集群中只有 Leader 可以处理 client 发送过来的请求,其他非 Leader 节点即使接收到请求也必须将其转发到 Leader 节点进行处理。集群中的成员分三种角色:Leader、Follower、Condidate候选人。
选举过程:集群初始状态下是没有 Leader 的, 集群中所有成员均是 Follower,在选举开始期间所有 Follower 均可参与选举、角色转变为 Condidate, Leader 由集群中所有的 Condidate 投票选出,最后获得投票最多的 Condidate 获胜,角色转变为 Leader,其余角色转变为 Follower 开始服从 Leader 领导。
选不出 Leader 时:引入了北洋时期袁世凯获选大总统的谋略,即选不出 Leader 不罢休,直到选出为止。一轮选不出 Leader,便令所有 Condidate 随机 sleep重新投票。
c.php关键字self与static
static 是$this 的升级版。($this指定的变化的对象,static 指定的是变化的类),这里注意对象和类的区别。
class P
{
public static function getChild() {
return static::class. '/'. self::class. '|'. __CLASS__;
}
public function get() {
return static::class. '<'. self::class. '|'. __CLASS__;
}
}
class C extends P {}
echo C::getChild(), PHP_EOL; //类调用,输出:C/P|P
$c = new C(); //对象调用
echo $c->get(). PHP_EOL; //输出:C
d.面向对象的“绕人”链表
参考《链表数据结构》,写完自己看不懂:
// 英雄类
class Hero{
public $data;
public $next=null;
public function __construct($no=0,$name='',$nickname=''){
$data['no'] = $no;
$data['name'] = $name;
$data['nickname'] = $nickname;
$this->data = $data;
}
}
$head=new Hero();
$hero1=new Hero(1,"宋江","及时雨");
$head->next=$hero1;
$hero2=new Hero(8,"卢俊义","玉麒麟");
$hero1->next=$hero2;
function print_list($cur){
while($cur->next!=null){
echo "姓名:".$cur->next->data['no'].'. '.$cur->next->data['name']."
";
$cur=$cur->next;
}
echo '**********************************
';
}
echo '';
//批量添加,链式传递&
function insert_list($node, ... $args)
{
foreach($args as $data){
$next = new Hero($data[0], $data[1], $data[2]);
$node->next = $next;
$node = $next; //注意迭代
}
}
print_list($hero2);
insert_list($hero2, [13,'赵小白','小白'], [6,'李兴河','小何'], [11,'张大河','大何']);
print_list($hero1);
print_list($head);
//排序,返回新序列
function sort_list($node, $order_field='no', $order_type="ASC"){
$list2array=[];
$node2 = $node;
while($node2->next != null){
$list2array[$node2->next->data[$order_field]] = [
$node2->next->data['no'],
$node2->next->data['name'],
$node2->next->data['nickname']
];
$node2 = $node2->next;
}
if( $order_type=="ASC"){
ksort($list2array);
}else{
krsort($list2array);
}
$head_node = new Hero();//写时复制
function insertls($node, $list2array) {
foreach($list2array as $data){
$next = new Hero($data[0], $data[1], $data[2]);
$node->next = $next;
$node = $next; //注意迭代
}
}
insertls($head_node, $list2array);
return $head_node;
}
$new_head = sort_list($head);
print_list($new_head);
上面提到迭代,使用Iterator试下:
Iterator::current — 返回当前元素 3
Iterator::key — 返回当前元素的键 4
Iterator::next — 向前移动到下一个元素 1.1
Iterator::rewind — 返回到迭代器的第一个元素 1.0
Iterator::valid — 检查当前位置是否有效 2
查完资料,放弃。