- 如何使用命令行(带参数)
- 如何使用多任务队列(如:发送邮件)
- 缓存支持文件缓存和Redis缓存
- 通过redis实现session共享存储 (不需要修改
php.ini
配置文件) - 符合REST架构设计的API,提供便利的API的版本号访问地址
- 引入Trait,实现了代码的复用
- 接入基于H+后台主题UI框架
- 基于Auth认证类的权限分配及menu菜单栏目管理过滤
- 结合GatewayWorker实现简单的聊天功能
- 服务端到客户端发/收送消息,通过框架发送,中间件为TP5
- 客户端到客户端发/收送消息,通过WEB客户端发送,中间件为GateWorker
- 自动加载历史聊天数据
- PHPExcel与ajax结合进行文件异步下载
思路:生成该文件并直接存储于当前目录,返回文件的下载地址,前台ajax成功返回后,通过返回的地址进行文件下载
- phpspreadsheet 导出文件支持Excel、Csv、Html格式导出
- 读取 Excel 上传文件后批量导入MySQL数据库
- 使用Parsedown扩展
Markdown
转换为html文件显示 - 模型闭包更新数据,更高级的使用
- 支付宝沙箱模式支付(无需商户账号)
配置路由请注意,异步回调为
post
,Route::post("api/:version/notify")
- 自定义日志
- 自定义日志目录(模块独立配置),项目根目录
/logs
Index
模块支持远程Socket调试日志打印到浏览器的console中- 免费socketlog-server服务:
slog.tinywan.com
- 自定义日志目录(模块独立配置),项目根目录
- 如何实现数据库自定义自增字段实现,方法:
get_next_id($model = 'order', $increase = 1)
,新增数据表_sequence_order
- 通过命令行自动每日凌晨进行
账户金额清算
和账户金额结算
- 分布式之延时任务方案解析
- 生成订单60秒后,给用户发短信
- 修改Redis配置文件,开启
键空间通知
,重启Redis服务 - 执行多任务队列
php think queue:work --daemon --queue multiTaskQueue
(发送短信) - 使用命令行开启订阅模式
php think pay psubscribe
(阻塞模式),Linux 守护进程。 - 设置订单有效期
setex S120012018033017194343904 3 value001
- 修改Redis配置文件,开启
- 延迟订单删除操作
- 通过
有序集合(sorted set)
实现 - 通过
有序集合(sorted set)
实现
- 通过
- 生成订单60秒后,给用户发短信
- 支付(API)网关 和支付渠道
- 支付网关对外提供唯一的服务接口
- 资金操作都需要通过网关分发到对应的渠道模块
- 调用渠道接口执行真正的资金操作
- 网关的功能是为业务提供通用接口
- 网关本身并不执行任何支付相关的业务逻辑
- Repository 模式实现业务逻辑和数据访问的分离
- 自定义异常类(针对接口)
- 如何自定义404和401页面
http_exception_template
- 阿里云短信服务接入:
\app\common\library\DySms::sendSms('13669361192', ['code'=>123456])
- UUID这个PHP扩展可以生成唯一识别码,可以个=能生成唯一的完全数字签名
- 根据银行卡账号获取所属银行
- 依赖注入详解
- [如何使用依赖注入解决多个缓存切换的依赖] (https://www.kancloud.cn/tinywan/tinywan_001/737001)
- 增加 yaconf 配置文件
- Rsa加密和解密
-
支付异步
和提现异步
以及转账异步
回调如何通过分布式队列去完成 - Swoole 接入
- 记录日志,由
use think\Log;
修改为use think\facade\Log;
自定义日志文件路径,请使用绝对路径:
'path' => Env::get('ROOT_PATH').'/logs'
- 队列配置文件的不同
- 5.0版本:
\application\extra\queue.php
- 5.1版本:
\application\config\queue.php
- thinkphp-queue 笔记
- 5.0版本:
- 视图输出
html
标签,{$html}
必须为{$html|raw}
- 模板渲染规则
小写+下划线
,如:addSidebar
则试图为add_sidebar.html
- 自增
setInc()
方法必须有默认值才可以自增,如果新增子弹NULL
是不可以的
定义接口(api)路由
Route::get("api/:version/token/user","api/:version.Token/getToken");
// 或者 \think\facade\Route::get("api/:version/token/user","api/:version.Token/getToken");
定义路由前访问地址:
http://tp51.env/api/v1.token/getToken
定义路由后访问地址:http://tp51.env/api/v1/token/user
通过命令行的方式执行一些URL访问不方便或者安全性较高的操作,如:清除缓存文件php think clear
namespace app\common\console;
use app\common\components\test\SystemUser;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
class CreateUser extends Command
{
protected function configure()
{
$this->setName('hello')
->addArgument('name', Argument::REQUIRED, "your name")
->addOption('city', null, Option::VALUE_REQUIRED, 'city name')
->setDescription('Say Hello');
}
protected function execute(Input $input, Output $output)
{
$name = trim($input->getArgument('name'));
$name = $name ?: 'thinkphp';
if ($input->hasOption('city')) {
$city = PHP_EOL . 'From ' . $input->getOption('city');
} else {
$city = '';
}
if ($name == 'systemUser'){
$res = PHP_EOL.$this->systemUser();
}
$res = $res ?: 'Default User';
$output->writeln("Hello," . $name . '!' . $city."\r\n".$res);
}
/**
* 创建系统用户
* @return string
*/
private function systemUser()
{
$model = new SystemUser();
return $model->create();
}
你必须在 configure() 方法中配置命令的名称,然后可选地定义一个帮助信息 和 输入选项及输入参数
app\common\components\test\SystemUser
为一个需要运行的组件
配置命令之后,然后在 application 目录下面的 command.php(如果不存在则创建)文件中添加如下内容:
return [
\app\common\console\CreateUser::class
];
在终端(terminal)中执行
-
方式一:
>php think hello Tinywan Hello,Tinywan! Default User
-
方式二:
>php think hello Tinywan --city shanghai Hello,Tinywan! From shanghai Default User
-
方式三:
>php think hello systemUser Hello,systemUser! createapp\common\components\test\SystemUser::create
-
方式四:
php think hello systemUser --city GanSu Hello,systemUser! From GanSu createapp\common\components\test\SystemUser::create
-
查看命令帮助:
>php think crontab --help Usage: crontab [options] [--] <name> Arguments: name the name of the task that crontab needs to run
-
执行MySQL数据库自动备份脚本:
>php think crontab mysqldump
- 快速生成控制器:
php think make:controller live/Blog
- 快速生成模型:
php think make:model index/Blog
- 快速生成中间件:
php think make:middleware Auth
- 创建验证器类:
php think make:validate index/User
trait有两个功能 :
- 提供如
interface
的合约 - 提供如
class
的实做 - 类成员优先级为:当前类 > Trait > 父类
- PHP中Trait详解及其应用
所以trait是一個看起來像interface,但用起來像class的東西。
队列任务代码:application\common\queue\Worker.php
workerQueue
任务队列功能
- 检查数据库状态,如果数据库为链接成功则直接删除任务
- 否则,给数据库插入一条记录
- 如果记录插入成功,则直接删除任务
- 否则延迟发送4次后不再发送
配置文件路径:application\config\queue
,配置如下所示:
return [
// Redis 驱动
'connector' => 'Redis',
// 任务的过期时间,默认为60秒; 若要禁用,则设置为 null
'expire' => 60,
// 默认的队列名称
'default' => 'default',
// redis 主机ip
'host' => '127.0.0.1',
// redis 端口
'port' => 6379,
// redis 密码
'password' => '',
// 使用哪一个 db,默认为 db0
'select' => 0,
// redis连接的超时时间
'timeout' => 0,
// 是否是长连接
'persistent' => false,
];
public function queue()
{
//当前任务所需的业务数据,不能为 resource 类型,其他类型最终将转化为json形式的字符串
$data = [
'email' => '[email protected]',
'username' => 'Tinywan' . rand(1111, 9999)
];
// 当前任务归属的队列名称,如果为新队列,会自动创建
$queueName = 'workerQueue';
// 将该任务推送到消息队列,等待对应的消费者去执行
$isPushed = Queue::push(Worker::class, $data, $queueName);
// database 驱动时,返回值为 1|false; redis驱动时,返回值为 随机字符串|false
if ($isPushed !== false) {
echo '['.$queueName.']'." Job is Pushed to the MQ Success";
} else {
echo 'Pushed to the MQ is Error';
}
}
浏览器访问推送消息:
http://tp51.env/index/index/queue
-
终端(terminal)执行命令:
> php think queue:work --daemon --queue multiTaskQueue
-
执行(消费)结果:
> php think queue:work --daemon --queue multiTaskQueue Processed: app\common\queue\Worker Processed: app\common\queue\Worker Processed: app\common\queue\Worke
以下为发送邮件队列测试:
/**
* 测试多任务队列
* @return string
*/
public function testMultiTaskQueue()
{
$taskType = MultiTask::EMAIL;
$data = [
'email' => '[email protected]',
'title' => "邮件标题".rand(111111,999999),
'content' => "邮件内容".rand(11111,999999)
];
$res = multi_task_Queue($taskType, $data);
if ($res !== false) {
return "Job is Pushed to the MQ Success";
} else {
return 'Pushed to the MQ is Error';
}
}
发送前先执行
php think queue:work --daemon --queue multiTaskQueue
$res = new Admin();
$re = $res->save(['username'=>'Tinyaiai'],function ($query){
$query->where('status','=',1)->where('id','=',5);
});
-
先来做个说明:
nginx
本身不能处理PHP,它只是个web服务器。当接收到客户端请求后,如果是php请求,则转发给php解释器处理,并把结果返回给客户端。如果是静态页面的话,nginx
自身处理,然后把结果返回给客户端。 -
nginx
下php解释器使用最多的就是fastcgi
。一般情况nginx
把php
请求转发给fastcgi
(即 php-fpm)管理进程处理,fastcgi
管理进程选择cgi
子进程进行处理,然后把处理结果返回给nginx
。 -
在这个过程中就牵涉到两个用户,一个是
nginx
运行的用户,一个是php-fpm
运行的用户。如果访问的是一个静态文件的话,则只需要nginx
运行的用户对文件具有读权限或者读写权限。 -
而如果访问的是一个php文件的话,则首先需要
nginx
运行的用户对文件有读取权限,读取到文件后发现是一个php文件,则转发给php-fpm
,此时则需要php-fpm
用户对文件具有有读权限或者读写权限。
- 统计8801端口连接数:
netstat -nat | grep -i "8801" | wc -l
- 查看TCP网络连接情况:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
- 查看 Mac/Linux 某端口占用情况
- 1、lsof -i:端口号
- 2、netstat -untlp|grep 端口号
- 软连接:
ln -s a b
a 就是源文件,b是链接文件名,其作用是当进入b目录,实际上是链接进入了a目录 删除软链接:
rm -rf b 注意不是 rm -rf b/