php 记录代码 / 页面执行时间
代码如下:
$t1 = microtime(true);
// ... 执行代码 ...
$t2 = microtime(true);
echo '耗时 '.round($t2-$t1, 3).' 秒';
microtime() 如果带有 true 参数,将返回一个浮点类型。
这样 t1 和 t2 得到的就是两个浮点数,相减之后得到之间的差。
由于浮点的位数很长,或者说不确定,所以再用 round() 取出小数点后 3 位。
代码如下:
$t1 = microtime(true);
// ... 执行代码 ...
$t2 = microtime(true);
echo '耗时 '.round($t2-$t1, 3).' 秒';
microtime() 如果带有 true 参数,将返回一个浮点类型。
这样 t1 和 t2 得到的就是两个浮点数,相减之后得到之间的差。
由于浮点的位数很长,或者说不确定,所以再用 round() 取出小数点后 3 位。
代码如下:
// 设置HTTP状态码
function http_header($num) {
$http = array(
100 => "HTTP/1.1 100 Continue",
101 => "HTTP/1.1 101 Switching Protocols",
200 => "HTTP/1.1 200 OK",
201 => "HTTP/1.1 201 Created",
202 => "HTTP/1.1 202 Accepted",
203 => "HTTP/1.1 203 Non-Authoritative Information",
204 => "HTTP/1.1 204 No Content",
205 => "HTTP/1.1 205 Reset Content",
206 => "HTTP/1.1 206 Partial Content",
300 => "HTTP/1.1 300 Multiple Choices",
301 => "HTTP/1.1 301 Moved Permanently",
302 => "HTTP/1.1 302 Found",
303 => "HTTP/1.1 303 See Other",
304 => "HTTP/1.1 304 Not Modified",
305 => "HTTP/1.1 305 Use Proxy",
307 => "HTTP/1.1 307 Temporary Redirect",
400 => "HTTP/1.1 400 Bad Request",
401 => "HTTP/1.1 401 Unauthorized",
402 => "HTTP/1.1 402 Payment Required",
403 => "HTTP/1.1 403 Forbidden",
404 => "HTTP/1.1 404 Not Found",
405 => "HTTP/1.1 405 Method Not Allowed",
406 => "HTTP/1.1 406 Not Acceptable",
407 => "HTTP/1.1 407 Proxy Authentication Required",
408 => "HTTP/1.1 408 Request Time-out",
409 => "HTTP/1.1 409 Conflict",
410 => "HTTP/1.1 410 Gone",
411 => "HTTP/1.1 411 Length Required",
412 => "HTTP/1.1 412 Precondition Failed",
413 => "HTTP/1.1 413 Request Entity Too Large",
414 => "HTTP/1.1 414 Request-URI Too Large",
415 => "HTTP/1.1 415 Unsupported Media Type",
416 => "HTTP/1.1 416 Requested range not satisfiable",
417 => "HTTP/1.1 417 Expectation Failed",
500 => "HTTP/1.1 500 Internal Server Error",
501 => "HTTP/1.1 501 Not Implemented",
502 => "HTTP/1.1 502 Bad Gateway",
503 => "HTTP/1.1 503 Service Unavailable",
504 => "HTTP/1.1 504 Gateway Time-out"
);
header($http[$num]);
}
INSERT INTO table1 SELECT * FROM table2;
INSERT INTO table1(filed1, ..., filedn) SELECT table2.filed1, ..., table2.filedn FROM table2;
INSERT into db1.table1(id, number, name)
SELECT stu.person_id
, stu.number
, person.name
FROM db2.t_stu_info AS stu
, db2.t_person_info as person
WHERE stu.person_id = person.id
一般电子商务网站都会遇到如团购、秒杀、特价之类的活动,而这样的活动有一个共同的特点就是访问量激增、上千甚至上万人抢购一个商品。
然而,作为活动商品,库存肯定是很有限的,如何控制库存不让出现超卖,以防止造成不必要的损失,是众多电子商务网站程序员头疼的问题,这同时也是最基本的问题。
总库存:4个商品
请求人:a、1个商品 b、2个商品 c、3个商品
$pdo->beginTransaction();
try{
$result = $pdo->query('select amount from s_store where postID = 12345');
if($result->amount > 0){
// quantity 为请求减掉的库存数量
$pdo->query('update s_store set amount = amount - quantity where postID = 12345');
}
// 没有错误则提交事务
$pdo->commit();
}catch($e \PDOException){
// 遇到错误则回滚事务
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
}
$pdo->beginTransaction();
try{
// 使用 SELECT ... FOR UPDATE 将此行数据锁住,在提交事务或者回滚事务时自动解开。
$result = $pdo->query('select amount from s_store where postID = 12345 for update');
if($result->amount < 0){
// 抛出异常
throw new \PDOException('库存不足');
}
// quantity 为请求减掉的库存数量
$pdo->query('update s_store set amount = amount - quantity where postID = 12345');
// 没有错误则提交事务
$pdo->commit();
}catch($e \PDOException){
// 遇到错误则回滚事务
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
}
在工作中,我们经常会遇到这样的问题,需要更新库存,当我们查询到可用的库存准备修改时,这时,其他的用户可能已经对这个库存数据进行修改了,导致,我们查询到的数据会有问题,下面我们就来看解决方法。
如果SELECT 后面若要UPDATE 同一个表单,最好使用SELECT ... UPDATE。
假设商品表单 products 内有一个存放商品数量的 quantity,在订单成立之前必须先确定 quantity 商品数量是否足够( quantity > 0 ),然后才把数量更新为 1 。
SELECT quantity FROM products WHERE id = 3; UPDATE products SET quantity = 1 WHERE id = 3;
为什么不安全呢?
高并发时会出现问题,如果我们需要在 quantity > 0 的情况下才能扣库存,假设程序在第一行 SELECT 读到的 quantity 是 2,但是当 MySQL 正准备要 UPDATE 的时候,可能已经有人把库存扣成 0 了,但是程序却浑然不知,将错就错的 UPDATE 下去了。因此必须利用事务机制来确保读取及提交的数据都是正确的。
BEGIN WORK; SELECT quantity FROM products WHERE id = 3 FOR UPDATE;
此时 products 数据中 id = 3 的数据被锁住,其它事务必须等待此次事务提交后才能执行。
SELECT * FROM products WHERE id = 3 FOR UPDATE;
事务 (transaction) 是由查询和/或更新语句的序列组成。用 begin、start transaction 开始事务,rollback 回滚事务,commit 提交事务。
在开始事务后,可以有若干个 SQL 查询或更新语句,每个 SQL 递交执行后,还应该有判断是否正确执行的语句,以确定下一步是否回滚,若都被正确执行则最后提交事务。
事务一旦回滚,数据库则保持开始事务前状态。就好象一个被编辑的文件不存盘退出,自然还是保持文件原来的样子。
所以,事务可被视为原子操作,事务中的 SQL,要么全部执行,要不一句都不执行。
如果需要一个事务,则必须用 PDO::beginTransaction() 方法来启动,一旦开始了事务,可用 PDO::commit() 或 PDO::rollBack()来完成,这取决于事务中的代码是否运行成功。
Tips: MySQL只有 InnoDB 驱动支持事务处理,默认 MyIsAM 驱动不支持。
连接数据库:
<?php
try {
// 数据库 PDO 连接
$pdo = new \PDO('mysql:host=localhost;dbname=mydb', 'root', 'root', array(PDO::ATTR_PERSISTENT => true));
// 开启异常处理
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $e) {
echo "数据库连接失败:".$e->getMessage();
exit;
}
事务处理:
在下面例子中,假设为新员工创建一组条目,分配一个为 23 的 ID。除了登记资料,还需要记录工资。
当版本库代码更新时,通过 git 的 webhook(git web 钩子)触发 push 事件。用户提交代码(git push)服务器的宝塔 webhook 插件拉取当前 git 最新代码(git pull)。
1、CentOS 服务器安装宝塔面板:宝塔面板
2、安装 git:
yum install git
Tips: Git 生成 SSH 公钥
3、宝塔面板软件商店安装 宝塔WebHook;
4、添加 HOOK 命令:
#!/bin/bash
echo ""
#输出当前时间
date --date='0 days ago' "+%Y-%m-%d %H:%M:%S"
echo "Start"
#判断宝塔WebHook参数是否存在
if [ ! -n "$1" ];
then
echo "param参数错误"
echo "End"
exit
fi
#git项目路径
gitPath="/www/wwwroot/web/$1"
#git 网址
gitHttp="http://git.xxxxx.com/web/$1.git"
echo "Web站点路径:$gitPath"
#判断项目路径是否存在
if [ -d "$gitPath" ]; then
cd $gitPath
#判断是否存在git目录
if [ ! -d ".git" ]; then
echo "在该目录下克隆 git"
git clone $gitHttp gittemp
mv gittemp/.git .
rm -rf gittemp
fi
#拉取最新的项目文件
git reset --hard origin/master
git pull
#设置目录权限
chown -R www:www $gitPath
echo "End"
exit
else
echo "该项目路径不存在"
echo "End"
exit
fi
默认情况下,用户的 SSH 密钥存储在其 ~/.ssh 目录下。(CentOS 存储在 /root/.ssh;Windows 存储在 C:\Users\Administrator\.ssh)
查看目录下是否存在 SSH 公钥:
$ cd ~/.ssh
$ ls
authorized_keys2 id_dsa known_hosts
config id_dsa.pub
id_dsa 或 id_rsa 文件应该成对出现,其中一个带有 .pub 扩展名。.pub 文件是你的公钥,另一个则是私钥。
ssh-keygen -t rsa -C "your@example.com"
your@example.com 是你的邮箱。
ssh -T git@github.com
git config --global user.name "yourname"
git config --global user.email "your@example.com"
再次修改插件,主要包含一下更新:
插件基于aliyun-oss-php-sdk Release 2.3.0开发, 若以后SDK开发包更新导致插件不可用,请到 我的博客 ^ - ^获取新版本插件, 如果我还用typecho还用阿里云就会更新。
请赋予 文件上传目录 以及 插件日志目录 写权限,否则可能导致上传失败。
若开启“在服务器保留备份”功能:
成功保存文件到OSS但没有成功保存到服务器的情况下插件不会报错, 这将导致当前文件在服务器上没有备份,但是会插件日志目录下生成错误日志"error.log",请定期查阅并清理。
运行在云应用引擎上的站点“在服务器保留备份”选项无效。
旧版本Typecho存在无法上传大写扩展名文件的bug,请更新Typecho程序。
查看已使用的磁盘情况:
df -HT
查看所有磁盘:
fdisk -l
查看指定磁盘的分区情况:
fdisk -l /dev/xvdb1
对磁盘进行分区:
fdisk /dev/xvdb1
查看刚刚分配的磁盘号:
fdisk -l
格式化磁盘:
mkfs -t ext4 /dev/xvdb1
-t 表示指定格式化磁盘的文件系统类型为ext4,默认不指定为ext2(比较老的linux文件系统类型)centos7默认系统格式是xfs格式,格式化磁盘的时候也可以指定类型为xfs格式;