分类 技术 下的文章

现代PHP语言令人兴奋的新特性

写太久股票了,写点和编程有关的东西。

最近准备重构一些老项目,PHP写的,听说PHP最近的新版里面加了不少新特性,整理了放这。

一、命名空间

5.3.0引入,使用虚拟层次组织PHP代码,为以后基于PSR的代码体系奠定了基础。命名空间的引入让类名冲突变的不太可能,并且让分布式的组件式开发变的方便起来。

// 为一个文件设置命名空间
namespace Symfony\Component\HttpFoundation;

// 为一个文件使用或引入另一个命名空间
use Symfony\Component\HttpFoundation\Response;

二、性状

5.4.0引入,关键字trait,性状这个翻译是抄的一本书上的。性状是类的部分实现,可以混入一个或多个PHP类里。

比如Web开发里常常需要验证表单提交过来的参数是否符合要求,或者更抽象,验证一个数组内的内容是否符合另一个数组定义的对应要求,比如长度,是否为数字,是否为空等。

之前的做法是在做表单验证的Model类里写一个通用的父类,然后让所有业务Model去继承这个父类,在父类里写通用的验证提交参数的方法。但这样的话,这个验证的方法只能在Model内使用。

如果想在Model以外的地方去验证某一个数组的内容是否符合要求该如何?可以使用trait来代替通用类的写法。
在一个trait里单独实现和验证相关的内容,然后在任意需要验证的类中引用trait即可。

<?php
trait TraitDemo {
    // Trait的实现
}

class ClassDemo {
    use TraitDemo;
    // Class的实现
}

三、生成器

5.5.0引入,generator在其他语言里经常能看到。生成器会根据需要计算并产出需要迭代的值。例如一个数组遍历,通常的方法会把整个数组放入内存里,然后依次读取处理。

而生成器不同,他并不将数组整个读进内存,而是每次只读取一条,把下次要处理的值生产出来,再循环的时候拿到上次生产的值进行处理,再生产下一次要处理的值。

<?php
function generatorDemo(){
    yield 1;
    yield 2;
    yield 3;
}

foreach(generatorDemo() as $item){
    echo $item, PHP_EOL;
}

// 输出
// 1
// 2
// 3

四、闭包

5.3.0时引入,闭包在创建的时候会封装其周围的运行状态,即使周围环境改变了,闭包内的状态依然可以保持。PHP里闭包也被称为匿名函数,虽然其他语言里,这两个是不同的东西。

闭包既可以作为函数被调用,被传入参数,也可以本身作为参数被传入其他函数。前面生成器每次迭代返回的都是Generator对象,闭包则是Closure类的对象,他们看起来是函数,其实都是对象。

<?php
$closure = function($demo){
    return 'hello ' . $demo;
}
echo $closure('world');
// 输出 hello world

$name = 'Heitaosu';
$closure2 = function($demo) use ($name) {
    return $demo . ' ' . $name;
};
$closure2('Hey,');
// 输出 Hey, Heitaosu

五、内置服务器

以前在玩RoR的时候,老是感叹,要是PHP啥时候也有这么方便的内置服务器就好了,现在也有了。5.4.0引入。

// 只允许本地使用4000端口访问
php -S localhost:4000
// 允许公开使用4000端口访问,一般是局域网,除非绑定了公网IP
php -S 0.0.0.0:4000
// 允许本地使用8000端口并指定php.ini配置文件
php -S localhost:8000 -c /path/to/php.ini

#读书笔记# Erlang趣学指南

什么是并发

给并发建模

一段代码:

-module(person).
-export([init/1]).

-module(person).表示这个文件包含用于person模块的代码,应该与文件名一致。

模块名必须以小写字母开头

,技术上说,模块名是一个原子。

-export([init/1]).是一个导出声明,表示模块里哪些函数从模块外部进行调用。类似于其他语言中的public关键字。没有包括在到导出声明里的函数是私有的,无法在模块外调用。

  • init/1表示可导出init函数,这个函数包含一个参数。
  • []是一个列表,用于罗列可导出模块的所有函数。

开始模拟

spawn(ModName, FuncName, [Arg1, Arg2, ..., ArgN])

Erlang运行spawn时,会创建一个新进程,

这个进程不是操作系统的进程,而是一个Erlang系统管理的轻量级进程


当进程创建完毕后,它便开始执行参数所指定的代码。

  • spawn的返回值是一个进程标识符,可以用来与其他创建的进程交互。
  • ModName是包含想要执行代码的模块名。
  • FuncName是模块里的函数名。
  • [Arg1, Arg2, ..., ArgN]是一个参数列表,包含想要执行的函数参数。
  • Erlang里的模块类似于其他语言中的类,而Erlang进程类似于其他语言中的实例对象

发送消息

A想对B说你好,Erlang里会是类似于这么一句话:

B ! {self(), "你好"}.
# Pid ! Msg 语法的意思是,发送消息Msg到Pid。self()的意思是发送消息的进程,即当前进程。

接收消息

B想接收A发送的消息,类似下面的写法:

receive
{From, Message} ->
...
# From会绑定A,Message就是发送的消息内容。
end

并发的好处

  • 性能
  • 可扩展性
  • 容错性
  • 清晰性

并发程序与并行计算机

  • 并发程序是一种用并发语言写的程序,编写并发程序是为了提升性能,可扩展性和容错性。
  • 并发编程语言拥有专门用于编写并发程序的语言结构,这些结构是编程语言的主要部分,在所有操作系统上都有相同表现。
  • 并行计算机是一种有多个处理单元同时运行的计算机。

顺序和并发编程语言

编程语言有人两种:顺序和并发,顺序语言被设计用于编写顺序程序,没有描述并发计算的语言结构。并发语言被设计于编写并发程序,语言本身带有表达并发性的结构。

在Erlang里,并发性是由Erlang虚拟机提供的,非操作系统或外部库。大多数顺序编程语言里,并发性都是以接口形式提供,指向操作系统的内部并发函数。

因为不依赖操作系统或外部库,所以Erlang的并发在所有操作系统下的表现都是一致的。

Erlang速览

Shell

$ erl
Erlang R16B ...
Eshell V5.9 (abort with ^G)
1> 123456 * 223344.
27573156864
  • $是操作系统提示符。
  • erl命令启动了Erlang shell,erlang shell以横幅信息和计数提示符>1作为响应。
  • 表达式末尾必须加句号结束。

=操作符

可以用=绑定一个值,像这样:

2> X = 123.
123
3> X * 2.
246

如果想改变变量的值,奇怪的事就会发生:

4> X = 999.
** exception error: no match of right hand side value 999

变量和原子的语法

进程、模块和编译

在shell里编译并运行 Hello world

在Erlang shell外编译