php常用类或方法
简单数据库查询封装
class MyDb {
private $mysqli=NULL;
function __construct($dbname) {
$configs = [
'dbname1'=>['xxx.xxx.com', 'user', 'pass', 'dbname1'],
];
if(! isset($configs[$dbname])) {
throw new Exception('未查询到DB');
}
list($host, $user ,$pass, $dname) = $configs[$dbname];
// print_r($host);die;
$this->mysqli = new \mysqli($host, $user, $pass, $dname, 3306);
$this->mysqli->set_charset('utf8mb4');
}
public function query($sql)
{
// echo $sql.PHP_EOL.PHP_EOL;
if(preg_match('/^delete/i', $sql)) return [];
if(preg_match('/^update/i', $sql)) return [];
$stmt = $this->mysqli->query($sql); $result = [];
if($stmt && preg_match('/^select/i', $sql)) {
$result = [];
while($obj = $stmt->fetch_assoc()) {
$result[] = $obj;
}
} else {
$result = $stmt;
}
return $result;
}
}
常用调用方法
// 输出变量简写
function pr(...$texts) {
echo '<pre>';
if(is_array($texts)) {
foreach($texts as $text) { print_r($text); }
} else {
print_r($texts);
}
die();
}
// 写文件日志简写
function pw(...$texts) {
$traces = debug_backtrace(); $last = $traces[0];
if(is_array($texts)) {
foreach($texts as $text) {
file_put_contents(dirname($last['file']).'/1.log', basename($last['file']).'->'.$last['line'].'->'.print_r($text, 1).PHP_EOL, 8);
}
} else {
file_put_contents(dirname($last['file']).'/1.log', basename($last['file']).'->'.$last['line'].'->'.print_r($text, 1).PHP_EOL, 8);
}
}
分表数据处理
数据库表拆成100张表,如果要对其中的数据做处理
$db = new MyDb('dbname');
for($i = 0; $i < 100; $i ++)
{
$lastId = 0; $limit = 100;
while(true)
{
// id>{$lastId} ORDER by id asc limit {$limit} 不能省略修改
$objs = $db->query(
"select * from Product_{$i} where id>{$lastId} ORDER by id asc limit {$limit}");
if(($ct = count($objs)) > 0)
{
foreach($objs as $obj)
{
// 取出的数据做业务处理
}
if($ct < $limit) break; // 小于$limit数,则数据取完
$lastId = $obj->id;
usleep(mt_rand(1000, 1000000));
}
else
{
break;
}
}
}
多进程调试
经常需要启动多个进程来调试, 可以使用以下代码
首先要确认开启pcntl模块, 且只能在linux环境下执行
启动100个子进程,并发查询数据库
$childs = array();
for($j = 0; $j < 100; $j++)
{
$pid = pcntl_fork();
if($pid == -1) die('Could not fork!');
if($pid) { // 父进程
echo "parent \n";
$childs[] = $pid;
} else {
// 这里子进程执行任务
$db = new MyDb('xxxx');
for($i = 0; $i< 1000; $i++) {
$db->query('/*slave*/select now()');
usleep(500);
}
exit();
}
}
while(count($childs) > 0) {
foreach($childs as $k=>$pid) {
// WNOHANG参数表示非阻塞等待,即如果没有子进程退出,则立即返回
$res = pcntl_waitpid($pid, $status, WNOHANG);
if($res == -1 || $res > 0) {
unset($childs[$k]);
}
}
sleep(1);
}
快速导出大量数据
$sql = 'select * from user';
$pdo = new \PDO( 'mysql:host=127.0.0.1;dbname=test', 'root', 'root' );
$pdo->setAttribute( \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$rows = $pdo->query($sql);
$filename = date('Ymd').'.csv';//设置文件名
header('Content-Type:text/csv');
header("Content-Disposition:attachment;filename={$filename}");
$out = fopen('php://output','w');
// 写入标题
fputcsv(
$out, [
'id',
'username',
'password',
'create_time'
]
);
foreach( $rows as $row ){
$line=[
$row['id'],
$row['username'],
$row['password'],
$row['create_time']
];
fputcsv($out, $line);
}
fclose($out);
$memory=round((memory_get_usage()-$startMemory)/1024/1024,3).'M'.PHP_EOL;
file_put_contents('/tmp/test.txt',$memory,FILE_APPEND);