xxq's blog

go phper


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

PDO基础操作类

发表于 2017-01-15   |   分类于 PHP

花了点时间写了个基础的PDO操作类,仅供需要的童鞋参考,也欢迎板砖来拍。
特性:预处理,字符转义,事务操作,ping

话不多说,上代码

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
<?php
/**
* PDO操作类
*
* User: xiangqian
* Date: 17/1/2
* Time: 下午5:19
*/
namespace Lib\Model;
use \Conf\MysqlConf;
class PdoModel
{
public $dbName; //数据库名称
private $dbConfig; //数据库配置
private static $_instance;
private static $dbh;
/**
* 构造方法
*
* PdoModel constructor.
* @param $dbName
*/
private function __construct($dbName)
{
$this->dbName = $dbName;
$this->dbConfig = MysqlConf::$dbConfig;
$dsn = "mysql:host={$this->dbConfig['host']};dbname={$this->dbName}";
self::$dbh = new \PDO($dsn, $this->dbConfig['username'], $this->dbConfig['password'], $this->dbConfig['options']);
}
/**
* mysql连接是否可用
*
* @return bool
*/
public static function ping()
{
try {
self::$dbh->getAttribute(\PDO::ATTR_SERVER_INFO);
} catch (\PDOException $e) {
if (strpos($e->getMessage(), 'MySQL server has gone away') !== false) {
return false;
}
}
return true;
}
/**
* 重置连接
*/
public static function resetConnect()
{
self::$_instance = null;
}
/**
* 不允许克隆
*/
public function __clone()
{
trigger_error('Not allowed to be cloned', E_USER_ERROR);
}
/**
* 获取实例对象
*
* @param string $dbName
* @return PdoModel
*/
public static function getInstance($dbName = 'testdb')
{
if (!isset(self::$_instance) || !(self::$_instance instanceof self)) {
self::$_instance = new self($dbName);
}
return self::$_instance;
}
/**
* 查询单条数据
*
* @param string $tableName
* @param array $where
* @param array $fields
* @return array|mixed
*/
public function getRow($tableName = '', array $where, $fields = [])
{
$fields = self::_parseFields($fields);
try {
$parseWhere = self::_parseWhere($where);
$sql = "SELECT {$fields} FROM `{$tableName}` WHERE {$parseWhere['whereStr']} LIMIT 1";
$stmt = self::$dbh->prepare($sql);
$stmt->execute($parseWhere['bindArr']);
return $stmt->fetch();
} catch (\PDOException $e) {
return [];
}
}
/**
* 查询列表数据数据 常规查询
*
* @param string $tableName
* @param array $where
* @param array $fields
* @param string $order
* @param int $skip
* @param int $limit
* @return array
*/
public function getList($tableName = '', array $where, $fields = [], $order = 'id asc', $skip = 0, $limit = 20)
{
$fields = self::_parseFields($fields);
try {
$parseWhere = self::_parseWhere($where);
$sql = "SELECT {$fields} FROM `{$tableName}` WHERE {$parseWhere['whereStr']} ORDER BY {$order} LIMIT {$skip}, {$limit}";
$stmt = self::$dbh->prepare($sql);
$stmt->execute($parseWhere['bindArr']);
return $stmt->fetchAll();
} catch (\PDOException $e) {
return [];
}
}
/**
* 查询 自己写复杂sql
*
* @param $sql
* @param bool $one
* @return array|mixed
*/
public function query($sql, $one = false)
{
$sql = addslashes($sql);
try {
$stmt = self::$dbh->query($sql);
return $one ? $stmt->fetch() : $stmt->fetchAll();
} catch (\PDOException $e) {
return [];
}
}
/**
* 删除数据
*
* @param string $tableName
* @param array $where
* @return int
*/
public function delete($tableName = '', array $where)
{
try {
$parseWhere = self::_parseWhere($where);
$sql = "DELETE FROM `{$tableName}` WHERE {$parseWhere['whereStr']}";
$stmt = self::$dbh->prepare($sql);
$stmt->execute($parseWhere['bindArr']);
return $stmt->rowCount();
} catch (\PDOException $e) {
return 0;
}
}
/**
* 更新数据
*
* @param $tableName
* @param array $where
* @param array $update
* @return int
*/
public function update($tableName, array $where, array $update)
{
try {
$parseUpdate = self::_parseUpdate($update);
$parseWhere = self::_parseWhere($where);
$sql = "UPDATE `{$tableName}` SET {$parseUpdate['whereStr']} WHERE {$parseWhere['whereStr']}";
$stmt = self::$dbh->prepare($sql);
$bindArr = array_merge($parseUpdate['bindArr'], $parseWhere['bindArr']);
$stmt->execute($bindArr);
return $stmt->rowCount();
} catch (\PDOException $e) {
return 0;
}
}
/**
* 插入语句
*
* @param $tableName
* @param array $arr
* @return int
*/
public function insert($tableName, array $arr)
{
$parseInsert = self::_parseInsert($arr);
try {
$sql = "INSERT INTO `{$tableName}` ({$parseInsert['keyStr']}) VALUES ({$parseInsert['bindKeyStr']})";
$stmt = self::$dbh->prepare($sql);
$re = $stmt->execute($parseInsert['bindArr']);
return $re ? self::$dbh->lastInsertId() : 0;
} catch (\PDOException $e) {
return 0;
}
}
/**
* 事务操作
*
* @param array $tranStr
* @return bool
*/
public function excuteTransaction(array $tranStr)
{
$re = false;
try {
self::$dbh->beginTransaction();
foreach ($tranStr as $stateStr) {
self::$dbh->exec($stateStr);
}
$re = self::$dbh->commit();
} catch (\PDOException $e) {
self::$dbh->rollBack();
}
return $re;
}
/**
* 解析where
*
* @param array $where
* @return array
* @throws \Exception
*/
private static function _parseWhere(array $where)
{
if (!is_array($where) || empty($where)) {
throw new \Exception('分析where语句失败, where参数不能为空');
}
$whereStr = '';
$bindArr = [];
foreach ($where as $k => $item) {
$bindKey = ':w_' . $k;
$whereStr .= "`{$k}` {$item['operate']} $bindKey AND ";
$bindArr[$bindKey] = $item['value'];
}
return [
'whereStr' => rtrim($whereStr, 'AND '),
'bindArr' => $bindArr
];
}
/**
* 解析update
*
* @param array $update
* @return array
* @throws \Exception
*/
private static function _parseUpdate(array $update)
{
if (!is_array($update) || empty($update)) {
throw new \Exception('分析update语句失败, update参数不能为空');
}
$whereStr = '';
$bindArr = [];
foreach ($update as $k => $value) {
$bindKey = ':k_' . $k;
$whereStr .= "`{$k}` = $bindKey AND ";
$bindArr[$bindKey] = $value;
}
return [
'whereStr' => rtrim($whereStr, 'AND '),
'bindArr' => $bindArr
];
}
/**
* 解析插入语句
*
* @param array $arr
* @return array
* @throws \Exception
*/
private static function _parseInsert(array $arr)
{
if (!is_array($arr) || empty($arr)) {
throw new \Exception('分析insert语句失败, arr参数不能为空');
}
$separator = ', ';
$keyStr = '';
$bindKeyStr = '';
$bindArr = [];
foreach ($arr as $k => $value) {
$bindKey = ':k_' . $k;
$keyStr .= "`{$k}` {$separator}";
$bindKeyStr .= $bindKey . $separator;
$bindArr[$bindKey] = $value;
}
return [
'keyStr' => rtrim($keyStr, $separator),
'bindKeyStr' => rtrim($bindKeyStr, $separator),
'bindArr' => $bindArr
];
}
/**
* 解析fields字段
*
* @param array $fields
* @return string
* @throws \Exception
*/
private static function _parseFields(array $fields)
{
$fieldStr = '';
if (empty($fields) || !is_array($fields)) {
return '*';
}
foreach ($fields as $field) {
if (!is_string($field)) {
throw new \Exception("field必须是字符串,field=" . json_encode($field), '-1');
}
$fieldStr .= "`{$field}`, ";
}
return rtrim($fieldStr, ', ');
}
}

PHP多进程(进程控制扩展pcntl)

发表于 2017-01-15   |   分类于 PHP

PHP是一门较早出现的WEB开发脚本语言,并由于其语法结构简单、易学、开源等特性迅速占领WEB开发脚本语言领域,并成为这个领域的龙头老大直至今日。PHP从一出生就被设计用来快速开发WEB应用,这也注定了它在某些方面的先天不足,例如在cli环境下处理大量数据的情况,或者在并发编程方面,都显得力不从心。

本文主要讲解基于PCNTL的PHP并发编程,虽然PHP本身不支持多进程,但基于Linux的PHP扩展PCNTL却可以提供多进程编程。网络上很多同类文章,但笔者进行多次尝试后发现,不是难以控制进程数量,就是有潜在产生僵尸进程或孤儿进程的危险,或者父进程阻塞难以获得更大的并发效果,且大多没有介绍FORK的原理,使得PHP程序员学习PCNTL并发编程尤为困难。本文力求解决这个问题。

FORK编程的大概原理是,每次调用fork函数,操作系统就会产生一个子进程,儿子进程所有的堆栈信息都是原封不动复制父进程的,而在fork之后,父进程与子进程实际上是相互独立的,父子进程不会相互影响。也就是说,fork调用位置之前的所有变量,父进程和子进程是一样的,但fork之后则取决于各自的动作,且数据也是独立的;因为数据已经完整的复制给了子进程。而唯一能够区分父子进程的方法就是判断fork的返回值。如果为0,表示是子进程,如果为正数,表示为父进程,且该正数为子进程的PID(进程号),而如果是-1,表示子进程创建失败

提个伪需求:顺序向一个文件输出2000000个数字0-1999999, 每个数字一行

常规思路:

1
2
3
4
5
6
<?php
$max = 2000000
$logFile = '/tmp/pcntl.log';
for ($i = 0; $i < $max; $i++) { //循环向文件写入数字
file_put_contents($logFile, $i . PHP_EOL, FILE_APPEND);
}

多进程(pcntl扩展):

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
<?php
$max = 2000000;
$workers = 10;
$logFile = '/tmp/pcntl.log';
pcntl_signal(SIGCHLD, SIG_IGN);
for ($i = 0; $i < $workers; $i++) {
$pid = pcntl_fork(); //创建子进程
if ($pid == -1) {
die('could not fork'); //错误处理:创建子进程失败时返回-1
}
if ($pid) {
//父进程会得到子进程号,所以这里是父进程执行的逻辑
//如果不需要阻塞进程,而又想得到子进程的退出状态,则可以注释掉pcntl_wait($status)语句
pcntl_wait($status, WNOHANG); //等待子进程中断,防止子进程成为僵尸进程。
} else {
//子进程得到的$pid为0, 所以这里是子进程执行的逻辑 执行处理逻辑
$lastId = $i === 0 ? 0 : $max / $workers * $i;
$maxId = $max / $workers * ($i + 1) - 1;
for ($j = $lastId; $j <= $maxId; $j++) {
file_put_contents($logFile, $j . PHP_EOL, FILE_APPEND);
}
exit;
}
}

time php pcntl.php
执行时间:
1、常规思路: php pcntl.php 2.24s user 4.56s system 97% cpu 6.981 total
2、多进程: php pcntl.php 0.02s user 0.00s system 23% cpu 0.086 total

MarkDown基础语法学习

发表于 2017-01-15   |   分类于 MarkDown

一级标题

二级标题

三级标题

四级标题

五级标题
六级标题

无序列表

  • 1
  • 2
  • 3

有序列表

  1. 1
  2. 2
  3. 3
  4. 4

这里是引用

插入链接

Baidu

插入图片

test

这是斜体1111

这是粗体1111

表格

Tables Are Cool
col 3 is right-aligned $1600
col 2 is centered $12
zebra stripes are neat $1

代码块

1
2
3
4
5
<?php
echo 'hello world';
for ($i = 0; $i < 10; $i++) {
echo $i . PHP_EOL;
}

分割线


PHP字符串操作函数归纳

发表于 2016-11-15   |   分类于 PHP

PHP 字符串函数是 PHP 核心的组成部分。

最常用函数:

  1. substr
  2. substr_compare
  3. substr_count
  4. substr_replace
  5. trim
  6. ucfirst
  7. ucwords
  8. strlen
  9. strcmp
  10. echo
  11. explode
  12. join
  13. ltrim
  14. md5
  15. ord
  16. print
  17. printf
  18. rtrim
  19. addslashes
  20. strtolower
  21. strtoupper
  22. strrev
  23. strstr
  24. strpos
  25. str_replace
  26. str_repeat
  27. str_shuffle
  28. str_split
  29. strcasecmp
  30. strchr strstr的别名
  31. strcmp
  32. addcslashes
  33. chop
  34. chr
  35. crc32
  36. crypt
  37. nl2br
  38. parse_str
  39. htmlspecialchars
  40. implode
  41. strip_tags
  42. stripcslashes
  43. stripslashes
  44. str_pad
  45. str_ireplace
  46. htmlentities

比较:

  1. strcoll
  2. strnatcasecmp
  3. strnatcmp
  4. strncasecmp
  5. strncmp

格式化:

  1. fprintf
  2. money_format
  3. number_format
  4. sprintf
  5. vfprintf
  6. vprintf
  7. vsprintf

编码:

  1. convert_uudecode
  2. convert_uuencode
  3. str_rot13

查找:

  1. strcspn
  2. stristr
  3. strpbrk
  4. stripos
  5. strrchr
  6. strripos
  7. strrpos

其他:

  1. bin2hex
  2. chunk_split
  3. convert_cyr_string
  4. count_chars
  5. get_html_translation_table
  6. hebrev
  7. hebrevc
  8. hex2bin
  9. html_entity_decode
  10. htmlspecialchars_decode
  11. lcfirst
  12. levenshtein
  13. localeconv
  14. md5_file
  15. metaphone
  16. nl_langinfo
  17. quoted_printable_decode
  18. quoted_printable_encode
  19. quotemeta
  20. setlocale
  21. sha1
  22. sha1_file
  23. similar_text
  24. soundex
  25. sscanf
  26. str_getcsv
  27. str_word_count
  28. strspn
  29. strtok
  30. strtr

排序算法归纳总结及PHP实现

发表于 2016-11-15   |   分类于 算法

哈哈

PHP数组函数归纳

发表于 2016-11-15   |   分类于 PHP

PHP数组是PHP最常用且最强大的数据结构,往往很多操作简单使用数组函数就可搞定,而无需写一大堆其他代码,增强代码执行效率和可维护性

最常用函数:

  1. array
  2. array_column
  3. array_keys
  4. array_reverse
  5. array_search
  6. array_sum
  7. array_unique
  8. array_values
  9. count
  10. in_array
  11. sizeof
  12. shuffle
  13. range
  14. array_count_values
  15. array_chunk
  16. array_key_exists
  17. array_merge
  18. array_rand
  19. array_replace
  20. key
  21. list
  22. array_map
  23. array_walk
  24. array_filter
  25. array_flip
  26. array_fill
  27. array_combine
  28. array_change_key_case
  29. array_pad
  30. array_slice

位置函数:

  1. current
  2. end
  3. next
  4. prev
  5. pos
  6. reset
  7. each

排序函数:

  1. array_multisort
  2. arsort
  3. asort
  4. krsort
  5. ksort
  6. natcasesort
  7. natsort
  8. rsort
  9. sort
  10. uasort
  11. uksort
  12. usort

栈及队列

  1. array_pop
  2. array_push
  3. array_shift
  4. array_unshift

差集

  1. array_diff_assoc
  2. array_diff_key
  3. array_diff_uassoc
  4. array_diff_ukey
  5. array_udiff
  6. array_udiff_assoc
  7. array_udiff_uassoc
  8. array_diff

交集

  1. array_intersect
  2. array_intersect_assoc
  3. array_intersect_key
  4. array_intersect_uassoc
  5. array_intersect_ukey
  6. array_uintersect
  7. array_uintersect_assoc
  8. array_uintersect_uassoc

其他

  1. array_fill_keys
  2. array_merge_recursive
  3. array_product
  4. array_reduce
  5. array_replace_recursive
  6. array_splice
  7. array_walk_recursive
  8. compact
  9. extract

PHP闭包

发表于 2016-11-14   |   分类于 PHP

php的闭包(Closure)也就是匿名函数。是PHP5.3引入的。

1
2
3
4
<?php
$a = function() use ($b) {
}

闭包的几个作用:

  1. 减少foreach的循环的代码
  2. 减少函数的参数
  3. 解除递归函数
  4. 关于延迟绑定

减少foreach的循环的代码

1
2
3
4
5
6
7
8
9
function myFunction($value, $key) {
echo "The key $key has the value $value" . PHP_EOL;
}
$arr = [
'a' => 'red',
'b' => 'blue',
'c' => 'yellow',
];
array_walk($arr, "myFunction");

减少函数的参数

解除递归函数

关于延迟绑定

本文参考

轩脉刃de刀光剑影

PHP扩展开发入门

发表于 2016-11-14   |   分类于 PHP

一级标题

Hello World

发表于 2016-09-23   |   分类于 hexo

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

12
xxq

xxq

记录平时学习

19 日志
10 分类
16 标签
github weibo
© 2017 xxq
由 Hexo 强力驱动
主题 - NexT.Pisces