PHP函数方法学习与总结

2018-03-10

PHP

Array

Immutable

map
1
2
3
4
5
$f = function($x, ...$ys) {};
array_map($f, $xs);
array_map($f, $xs, ...$yss);
array_map(null, $xs);
array_map(null, $xs, ...$yss);
1
2
3
4
5
6
7
xs.map(f)
xs.map((x, i) => {
const ys = yss.map((ys, i) => ys[i])
// ..
})
[xs]
[xs, ...yss]
filter
1
2
array_filter($xs, $f);
array_filter($xs, null);
1
2
xs.filter(f)
xs.filter(id)
reduce
1
2
array_reduce($xs, $f, $init);
array_reduce(array_reverse($xs), $f, $init);
1
2
xs.reduce(f, init)
xs.reduceRight(f, init)
traverse
1
2
3
4
$f = function($x, $key) {}
array_walk($xs, $f);
foreach ($xs as $x)
foreach ($xs as $key => $val)
1
xs.forEach(f)
slice
1
array_slice($xs, $start, $len);
1
2
const end = start + len
xs.slice(start, end)
find
1
array_search($x, $xs); // return false if not found
1
2
3
4
xs.indexOf(x)
xs.find(f)
xs.findIndex(f)
xs.includes(x)
length
1
count($xs);
1
xs.length
has
1
2
array_key_exists($key, $xs);
isset($xs[$key]); // return false if null
1
2
Reflect.has(xs, key)
!!xs[key]
keys / values
1
2
array_keys($xs);
array_values($xs);
1
2
Object.keys(xs)
Object.values(xs)
unique
1
array_unique($xs);
1
[...new Set(xs)]
fill
1
array_fill($start, $len, $x); // fill by ref
1
2
3
const end = start + len
Array(end).fill(x, start, end) // fill by ref
Array.from(Array(end), (_, i) => start <= i && i < end ? x : undefined) // fill by val
concat / merge
1
array_merge(...$xss);
1
2
[].concat(...xss)
Object.assign({}, ...xss)
zip
1
array_combine($xs, $ys);
1
xs.reduce((acc, x, i) => ({ ...acc, { [x]: ys[i] } }), {})
sum / product
1
2
array_sum($xs);
array_product($xs);
1
2
xs.reduce((acc, x) => acc + x, 0)
xs.reduce((acc, x) => acc * x, 1)
count
1
array_count_values($xs);
1
xs.reduce((acc, x) => (Reflect.has(acc, x) ? acc[x]++ : (acc[x] = 1)) && acc, {})

Mutable

push / pop / unshift / shift
1
2
3
4
5
$xs[] = $x;
array_push($xs, ...$ys);
array_pop($xs);
array_unshift($xs, ...$ys);
array_shift($xs);
1
2
3
4
5
6
7
8
9
10
// Mutable
xs.push(...ys)
xs.pop()
xs.unshift(...ys)
xs.shift()
// Immutable
[...xs, ...ys]
xs.slice(0, -1)
[...ys, ...xs]
xs.slice(1)
splice
1
array_splice($xs, $start, $len, $ys);
1
xs.splice(start, len, ...ys)

String

split
1
explode($seperator, $str);
1
str.split(seperator)
join
1
implode($seperator, $xs);
1
xs.join(seperator)
length
1
strlen($str);
1
str.length
substr
1
substr($str, $start, $len);
1
2
3
const end = start + len
str.slice(start, end)
str.substr(start, len)

Function

curry
1
2
3
4
5
6
7
8
9
10
11
12
$curry = function($f, $len = -1) use(&$curry) {
if (!~$len) {
$ref = new ReflectionFunction($f);
$len = $ref -> getNumberOfParameters();
}
return function(...$args) use($curry, $f, $len) {
$sub = count($args);
return $sub < $len ? $curry(function(...$rest) use($f, $args) {
return $f(...$args, ...$rest);
}, $len - $sub) : $f(...$args);
};
};
1
2
3
4
const curry = (f, len = f.length) => (...args) => {
const sub = args.length
return sub < len ? curry((...rest) => f(...args, ...rest), len - sub) : f(...args)
}
compose
1
2
3
4
5
6
7
8
9
10
$compose = function(...$funcs) {
$len = count($funcs);
return $len ? function(...$args) use($funcs, $len) {
return array_reduce(array_reverse(array_slice($funcs, 0, -1)), function($composed, $f) {
return $f($composed);
}, $funcs[$len - 1](...$args));
} : function($arg) {
return $arg;
};
};
1
2
3
4
5
6
const compose = (...funcs) => {
const len = funcs.length
return len ? (...args) => funcs.slice(0, -1).reduceRight(
(composed, f) => f(composed), funcs[len - 1](...args)
) : arg => arg
}

Yii

WebApplication

Create
1
Yii::createWebApplication($config) -> run();
retrieve
1
Yii::app() // Singleton

Components

retrieve
1
Yii::app() -> $component;

Controller

Route

default
1
2
"https://hostname/index.php?r=$module/$controller/$action&param=$param..."
$url = $this -> createUrl($route, $param);
User-friendly
1
2
3
4
5
6
7
8
9
// config.php
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules': array(
// ...
)
)
"https://hostname/$module/$controller/$action?param=$param..."

Action

1
2
3
4
5
6
7
8
9
10
class CommonController extends CController {
public function actions() {
return array(
'edit' => 'application.controllers.common.EditAction',
)
}
public function actionCreate() {
// ...
}
}
1
2
3
4
5
class EditAction extends CAction {
public function run() {
// ...
}
}

Filter (Middleware)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CommonController extends CController {
public function filters() {
return array(
'logger - index',
array('application.filters.HelloFilter + index'),
);
}
public filterLogger($filterChain) {
echo 'before';
$filterChain -> run();
echo 'after';
}
// ...
}
1
2
3
4
5
6
7
8
9
class HelloFilter extends CFilter {
protected function preFilter($filterChain) {
echo 'Hello';
return true; // this -> filter invoke $filterChain -> run()
}
protected function postFilter($filterChain) {
echo 'World';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Comparion
// Koa: Expressive HTTP middleware framework for node.js
import Koa from 'koa'

const app = new Koa()

app.use(async function(ctx, next) {
console.log('before')
await next()
console.log('after')
})

app.use(ctx => ctx.body = 'Hello World')

app.listen(3000)

Dependency Injection

1
2
3
4
5
6
7
8
9
10
11
class Controller extends CController {
public function __get($name) {
$factory = Factory::getInstance();
$this -> $name = $factory -> getClass($name);
return $this -> $name;
}
public function __set($name, $value) {
$this -> $name = $value;
}
// ...
}

Model

Db

multiple databases
1
2
3
4
5
// config.php
'db_common' => array(
'class' => 'CDbConnection',
// other config options
)
autoConnect
1
$connection = Yii::app() -> db;
connect
1
2
$connection = new CDbConnection($dsn, $username, $password);
$connection -> active = true;

Database Access Objects

command
1
$command = $connection -> createCommand($sql);
execute
1
$command -> execute();
query
1
2
$dataReader = $command -> query(); // forward-only stream
$data = $dataReader -> readAll();
1
2
3
4
$data = $command -> queryAll();
$data = $command -> queryRow();
$data = $command -> queryColumn();
$data = $command -> queryScalar();
transaction
1
2
3
4
5
6
7
8
$transaction = $connection -> beginTransaction();
try {
// sql
$transaction -> commit();
}
catch (Exception $err) {
$transaction -> rollback();
}
bind
1
2
3
4
5
$sql = 'SELECT name FROM students WHERE id=:id';
$command = $connection -> createCommand($sql);
$command -> bindParam(':id', $id);
$command -> bindValue(':id', 0);
$data = $command -> queryRow();

Query Builder

command
1
2
3
4
$command = $connection -> createCommand()
-> select('name')
-> from('students')
-> where('id=:id', array(':id' => $id));

Active Record

model
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Student extends CActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'students';
}
public function primaryKey() {
return 'id';
}
public function rules() {
return array(
array('name', 'length', 'max' => 30),
);
}
public function relations() {
return array(
'papers' => array(self::HAS_MANY, 'Paper', 'author_id'),
);
}
}
class Paper extends CActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'papers';
}
public function primaryKey() {
return 'id';
}
public function relations() {
return array(
'author' => array(self::BELONGS_TO, 'Student', 'author_id'),
);
}
}
connection
1
$connection = Student::model() -> dbConnection;
create
1
2
3
4
$student = new Student;
$student -> id = 0;
$student -> name = 'yanshi';
$student -> save(); // validation: invoke $student -> rules()
retrieve
1
2
3
4
5
6
7
8
9
10
11
$student = Student::model() -> find('id=:id', array(':id' => $id));
$student = Student::model() -> find(array(
'condition' => 'id=:id',
'param' => array(':id' => $id),
))
$student = Student::model() -> findByPk($id);
$student = Student::model() -> findByAttributes(array('name' => 'yanshi'));
$student = Student::model()
-> findBySql('SELECT name FROM students WHERE id=:id', array(':id' => $id));
// find would return null if not found
// findAll would return an empty array if not found
1
2
3
4
$count = Student::model() -> count('name=:name', array(':name' => 'yanshi'));
$count = Student::model()
-> countBySql('SELECT count(*) FROM students WHERE name=:name', array(':name' => 'yanshi'));
$exists = $students -> exists('name=:name', array(':name' => 'yanshi'));
update
1
2
3
$student = Student::model() -> findByPk(0);
$student -> name = 'fanxue';
$student -> save();
delete
1
$student -> delete();
join
1
2
3
4
5
$papers = Paper::model() -> findAll(array(
'condition' => 'author.id=:id',
'param' => array(':id' => $id),
'with' => array('author'),
));
区别bindParam,bindValue,bindValues
  • bindParam 绑定变量的引用
  • bindValue 绑定变量的值或者常量值
  • bindValues 绑定多个值
AR调用save具体对应哪些操作
  • $model 由 new 创建,执行 INSERT
  • $model 由 find 返回,执行 UPDATE
1
$model -> save(true, $attributes); // attributes need to be saved
1
2
$model -> updateAll($attributes, $condition, $param);
$model -> updateByPk($pk, $attributes, $condition, $param);
empty,isset各种调用情况的返回值
  • empty
    • “”
    • 0
    • 0.0
    • “0”
    • NULL
    • FALSE
    • array()
    • a variable declared, but without a value
  • isset
    • variable exsits and has value other than NULL
解释Yii的路由解析
  • showScript: false

  • 入口文件添加 .htaccess 配置 Apache

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Options +FollowSymLinks
    IndexIgnore */*
    RewriteEngine on

    # if a directory or a file exists, use it directly
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    # otherwise forward it to index.php
    RewriteRule . index.php
设置header
1
header("Access-Control-Allow-Origin: *");
redirect和forward的区别
1
2
$this -> redirect($this -> createUrl("$controller/$action"));
$this -> forward("$controller/$action");
PHP怎么在长时间请求下不断往前端输出
1
2
3
4
5
6
7
8
ob_get_level() || ob_start();
for ($i = 0; $i < 5; $i++) {
echo $i . ' ';
ob_flush();
flush();
sleep(1);
}
ob_end_flush();
SESSION锁
1
session_write_close();