PHP中如何实现多态的机制Hook机制

大家好,我是,今天为大家带来centOS下 利用 webhook 来实现项目自动部署。
场景:在coding上有一个hexo_blog的远程git仓库。
每次push新的文章上去后,还要登陆远程服务器去pull代码,感觉非常不方便。这里用webhook来解决这个问题。
1.创建apache 部署公钥
cd /usr/share
sudo chown apache httpd/ #修改httpd目录的所有者
sudo -Hu apache ssh-keygen -t rsa # 一直回车下去
sudo cat /usr/share/httpd/.ssh/id_rsa.pub # 查看生成的密钥内容,复制全部
2.将公钥部署到远程服务器上(coding为例子)
3.给予apache操作项目目录的权限
直接给目录777权限。。简单粗暴
sudo chmod 777 /var/www/hexo_blog/ -R
(或者也可以新建个用户组,把ftp和apache添加到该分组,给予该组权限)
4. 编写钩子(hook)
这里我为了达到hook的统一管理,我直接在www下建立了一个webhooks文件。
创建钩子 hexo_blog.php
error_reporting(1);
//需要自动部署的项目目录
'/var/www/hexo_blog';
//coding填写的令牌(在第六点配置,防止别人恶作剧)
$token = 'shelter';
//验证令牌
$json = json_decode(file_get_contents('php://input'), true);
if (empty($json['token']) || $json['token'] !== $token) {
exit('error request');
//这里因为我的git不支持直接git pull,所以带上了远程库名和分支,'2&&1'是让执行管道输出结果。
echo shell_exec("cd $dir && git checkout -f && git pull coding master 2&&1");
编写好钩子后,需要先手动使用apache的身份pull一下。执行
cd /var/www/hexo_blog
sudo -u apache git pull coding master
第一次连接需要输入yes,确认连接(这个坑,会导致令牌错误)。
pull成功!
5.配置钩子URL到远程仓库
nice!centOS下,利用webhook实现自动部署成功!
本文章首发在
认真,可以让事情变得出乎意料地好!
附加内容, 使用此功能的话, 会给所有参加过讨论的人发送提醒.
我要举报举报该,理由是:
垃圾广告信息:恶意灌水、广告、推广、测试等内容
违规内容:色情、暴利、血腥、敏感信息等
不友善内容:人身攻击、挑衅辱骂、恶意行为
其他理由:请补充说明
<button class="btn btn-success popover-with-html"
data-toggle="modal" data-target="#payment-qrcode-modal" data-content="如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!可以修改个人资料「支付二维码」开启打赏功能。">
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
您需要登陆以后才能留下评论!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
请使用微信扫描二维码。
时长:07:37 &&
将托管在 packagist.org 和 github.com 的扩展包使用国内 CDN 加速
GitHub Laravel 扩展包 TOP 250
Lumen 是为速度而生,专注于构建无状态 API 的 Laravel 精简版
速查表方便快速查询框架功能,支持手机访问,支持中英文版本
Laravel 中文文档,由社区用户翻译和维护,将会保持一直更新
此文档的目的,就是为了提高技术团队的凝聚力、一致性和生产效率。
开发环境的部署,开发者工具的选择,适用于 Mac 和 Windows。
PHP 扩展依赖工具 Composer 的官方文档翻译,每年校对
全文搜索分析引擎 Elasticsearch PHP 端文档中文翻译
Lumen 中文文档,由社区用户翻译和维护,将会保持一直更新
GraphQL PHP 项目的中文文档,教你如何开发 GraphQL API 接口
一些撰写文档的技巧和思路,一个教你写出好文档的文档。
本系列文章为 laracasts.com 的系列视频教程的课程笔记
PSR 是由 PHP FIG 组织制定的 PHP 规范,是 PHP 开发的实践标准。
设计模式是 PHP 架构师必备知识,本文档完整收录了 PHP 相关的设计模式。
Laravel 下知名扩展包 Dingo API 的中文文档,Laravel API 开发必知必会不多说什么,用于做插件,消息监听之类的东西,反正用处挺大的,不清楚的请移步看看。
  当然,代码之后只有使用的测试,而没有删除的测试,各种问题自行解决吧,还有功能不强,理论上应该可以设置优先级才对,但是这里不行,不完善的原因吧。
  基本原理还是很简单的,用列表存储对应的调用函数或方法,然后执行的时候调用并且返回一下就行了。还有钩子的作用是修改数据,所以必须传递一个参数过去,即使你用不到任何参数,发送个null参数过去也是可以的,并非没有意义,而是有时候部分数据很难直接调用,要使用全局变量或者通过其他方式获取的时候,空值也是不错的,至于返回对象,这个也必须的。
先贴类代码。
namespace C
* 系统钩子
* @author loveyu
class Hook{
* 用于存放对应的构造列表
* @var array
private $_hook_
* 构造方法
public function __construct(){
// TODO: Implement __construct() method.
$this-&_hook_list = array();
* 添加一个钩子到系统
* @param string
* @param callback $func
public function add($name, $func){
if(!isset($this-&_hook_list[$name])){
$this-&_hook_list[$name] = array();
if(is_array($func)){
$this-&_hook_list[$name][get_class($func[0]) . ":" . $func[1]] = $
$this-&_hook_list[$name][$func] = $
* 应用钩子,至少包含一个参数名
* @param string $name
* @param mixed
$param1 第一个参数
* @return mixed 返回调用的第一个参数
public function apply($name, $param1){
if(isset($this-&_hook_list[$name])){
$args = array_slice(func_get_args(), 1);
foreach($this-&_hook_list[$name] as $v){
$param1 = call_user_func_array($v, $args);
$args[0] = $param1;
return $param1;
* 移除对应的钩子
* @param string
$name 钩子名称
* @param callback|string $func 钩子对应的调用方法
public function remove($name, $func = ''){
if(isset($this-&_hook_list[$name])){
if(empty($func)){
unset($this-&_hook_list[$name]);
if(is_array($func)){
if(isset($this-&_hook_list[$name][get_class($func[0]) . ":" . $func[1]]))
unset($this-&_hook_list[$name][get_class($func[0]) . ":" . $func[1]]);
if(isset($this-&_hook_list[$name][$func]))
unset($this-&_hook_list[$name][$func]);
}然后是测试代码。
* 系统钩子测试文件
require("../core/hook.php");
$hook = new \Core\Hook();
* 回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
function test_hook_callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
class test_hook_class{
* 类方法回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
public function callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
* 静态方法回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
public static function static_callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
//函数回调
$hook-&add('test_hook', 'test_hook_callback');
//静态方法回调
$hook-&add('test_hook', 'test_hook_class::static_callback');
//实例化类
$test_class = new test_hook_class();
//添加方法
$hook-&add('test_hook', array($test_class, 'callback'));
//需要处理的数据
$data = "loveyu";
//执行回调函数,顺序为添加顺序,必须存在两个及以上参数
$data = $hook-&apply('test_hook', $data, 1, 2);
//输出最终数据
echo "\n".$
接着是运行结果输出数据。
Run at:test_hook_callback
Run at:test_hook_class::static_callback
Run at:test_hook_class::callback
{1[test_hook_callback]2}
{1[test_hook_class::static_callback]2}
{1[test_hook_class::callback]2}
PHP中的钩子是什么?
PHP HOOK的若干方法
(插件设计与简单应用)php中钩子(hook)的应用示例demo
php项目自动部署(利用webhook)
浅谈PHP中的钩子
php中的钩子理解及应用
没有更多推荐了,在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
$hooks = function($meta, $type) use ($inspector, $instance)
if (isset($meta[$type]))
$run = array();
foreach ($meta[$type] as $method)
$hookMeta = $inspector-&getMethodMeta($method);
if (in_array($method, $run) && !empty($hookMeta["@once"]))
$instance-&$method();
$run[] = $
$hooks($methodMeta, "@before");
这个hooks function里面有一个use是怎么回事?
想不通。。。。望大师告知
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
5.3 新增的闭包语法中,use 用来捕捉变量到匿名函数内,见:
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。Gitlab或者GitHub利用webhook实现push时项目自动部署
Author:飘易 Source:
Categories: PostTime: 10:20:01
前提:1、Git服务器是指已经安装了Gitlab的Git管理服务器(Github的很多功能和Gitlab类似);2、生产服务器是指配置好网站运行环境的测试服务器,默认apache的运行用户身份是www用户。Git webhook以www用户实现自动部署的步骤:1、在Git服务器上创建一个普通git用户(无需密码),如server-115.159.10.10,然后把这个用户加入到目标项目里的成员里,只需要有pull权限即可,飘易一般设置为Reporter。2、在生产服务器上为www用户生成 SSH 公钥,路径一般在 /home/www/.ssh/,把生成的公钥 id_rsa.pub 复制粘贴到Git服务器上第一步里的普通用户的ssh公钥里生成命令:sudo&-u&www&ssh-keygen3、【可选】切换用户身份从root变成www,注意要把www的默认shell从/sbin/nologin改成/bin/bash,不然无法cd和git pull等;注:www用户没有密码,而Linux的pam验证拒绝没有密码的用户登录系统,所以我们不用担心www用户可以直接登录系统。su&-&www4、首次从git服务器上抓取资源用clone,指定目录需要为空git&clone&git@git.a.net:li/test.git&/storage/wwwroot/qy.a.net/如果上面的第3步不做的话,可以模拟www用户身份执行:sudo&-u&www&git&clone&git@git.a.net:li/test.git&/storage/wwwroot/qy.a.net/5、先cd到项目根目录,后续再抓取直接pullgit&pull模拟www用户身份执行:sudo&-u&www&git&pull6、网站根目录下放置 git-webhook-handler.php 自动部署文件,然后Git服务器的对应项目的 webhooks 配置上该文件的网址(Push events),需启用php的shell_exec函数。其中Webhooks的push推送事件发生时,会向设置的URL上推送一个json消息,消息格式如下:Push eventsTriggered when you push to the repository except when pushing tags.Request header:X-Gitlab-Event:&Push&HookRequest body:{
&&&object_kind&:&&push&,
&&&before&:&&9fee5ea6a1f80f22&,
&&&after&:&&daf094c3e6c9efb5d27d7&,
&&&ref&:&&refs/heads/master&,
&&&checkout_sha&:&&daf094c3e6c9efb5d27d7&,
&&&user_id&:&4,
&&&user_name&:&&John&Smith&,
&&&user_email&:&&&,
&&&user_avatar&:&&https://s.gravatar.com/avatar/d4cb6bd6?s=8://s.gravatar.com/avatar/d4cb6bd6?s=80&,
&&&project_id&:&15,
&&&project&:{
&&&&&name&:&Diaspora&,
&&&&&description&:&&,
&&&&&web_url&:&http://example.com/mike/diaspora&,
&&&&&avatar_url&:null,
&&&&&git_ssh_url&:&:mike/diaspora.git&,
&&&&&git_http_url&:&http://example.com/mike/diaspora.git&,
&&&&&namespace&:&Mike&,
&&&&&visibility_level&:0,
&&&&&path_with_namespace&:&mike/diaspora&,
&&&&&default_branch&:&master&,
&&&&&homepage&:&http://example.com/mike/diaspora&,
&&&&&url&:&:mike/diaspora.git&,
&&&&&ssh_url&:&:mike/diaspora.git&,
&&&&&http_url&:&http://example.com/mike/diaspora.git&
&&&repository&:{
&&&&&name&:&&Diaspora&,
&&&&&url&:&&:mike/diaspora.git&,
&&&&&description&:&&&,
&&&&&homepage&:&&http://example.com/mike/diaspora&,
&&&&&git_http_url&:&http://example.com/mike/diaspora.git&,
&&&&&git_ssh_url&:&:mike/diaspora.git&,
&&&&&visibility_level&:0
&&&commits&:&[
&&&&&&&id&:&&bdcd7f8b4d5a946b0b91f9dacd7327&,
&&&&&&&message&:&&Update&Catalan&translation&to&e38cb41.&,
&&&&&&&timestamp&:&&T14:27:31+02:00&,
&&&&&&&url&:&&http://example.com/mike/diaspora/commit/bdcd7f8b4d5a946b0b91f9dacd7327&,
&&&&&&&author&:&{
&&&&&&&&&name&:&&Jordi&Mallach&,
&&&&&&&&&email&:&&jordi@softcatala.org&
&&&&&&&added&:&[&CHANGELOG&],
&&&&&&&modified&:&[&app/controller/application.rb&],
&&&&&&&removed&:&[]
&&&&&&&id&:&&daf094c3e6c9efb5d27d7&,
&&&&&&&message&:&&fixed&readme&,
&&&&&&&timestamp&:&&T23:36:29+02:00&,
&&&&&&&url&:&&http://example.com/mike/diaspora/commit/daf094c3e6c9efb5d27d7&,
&&&&&&&author&:&{
&&&&&&&&&name&:&&GitLab&dev&user&,
&&&&&&&&&email&:&&gitlabdev@dv6700.(none)&
&&&&&&&added&:&[&CHANGELOG&],
&&&&&&&modified&:&[&app/controller/application.rb&],
&&&&&&&removed&:&[]
&&&total_commits_count&:&4
}自动部署文件&git-webhook-handler.php 代码如下:&?php
//git&webhook&自动部署脚本
//项目存放物理路径
$path&=&&/storage/wwwroot/qy.a.net/&;
$requestBody&=&file_get_contents(&php://input&);
if&(empty($requestBody))&{
&&&&die(&#39;send&fail&#39;);
$content&=&json_decode($requestBody,&true);
//若是主分支且提交数大于0
if&($content[&#39;ref&#39;]==&#39;refs/heads/master&#39;&&&&$content[&#39;total_commits_count&#39;]&0)&{
&&&&$res&=&shell_exec(&cd&{$path}&&&&git&pull&2&&1&);//以www用户运行
&&&&$res_log&=&&#39;-------------------------&#39;.PHP_EOL;
&&&&$res_log&.=&$content[&#39;user_name&#39;]&.&&#39;&在&#39;&.&date(&#39;Y-m-d&H:i:s&#39;)&.&&#39;向&#39;&.&$content[&#39;repository&#39;][&#39;name&#39;]&.&&#39;项目的&#39;&.&$content[&#39;ref&#39;]&.&&#39;分支push了&#39;&.&$content[&#39;total_commits_count&#39;]&.&&#39;个commit:&#39;&.&PHP_EOL;
&&&&$res_log&.=&$res.PHP_EOL;
&&&&file_put_contents(&git-webhook.txt&,&$res_log,&FILE_APPEND);//追加写入
}如果本地有修改,希望强制用远程的库更新:git&fetch&--all
git&reset&--hard&origin/master当我们希望不使用cd命令先到项目根目录的时候(对应上面不做第3步),可以使用git参数 --git-dir 和 --work-tree:以www用户身份执行:
shell_exec(&cd&{$path}&&&&git&pull&2&&1&)
shell_exec(&git&--git-dir={$path}.git&fetch&&&&git&--git-dir={$path}.git&--work-tree={$path}&merge&origin/master&2&&1&)注意,centos6上默认的git版本是1.7,而git 1.7在,所以需要我们先fetch再merge!cd&/
sudo&-u&www&git&--git-dir=/storage/wwwroot/test/.git&fetch
sudo&-u&www&git&--git-dir=/storage/wwwroot/test/.git&--work-tree=/storage/wwwroot/test/&merge&origin/master而在git 1.8.5以上则可以直接使用下面的命令:sudo&-u&www&git&--work-tree=/storage/wwwroot/test/&--git-dir=/storage/wwwroot/test/.git&pull上述的shell_exec(&cd&{$path}&&&&git&pull&2&&1&)也可以使用下面的命令:cd&$path
git&reset&--hard&origin/master
git&clean&-f
git&checkout&masterphp里执行:shell_exec(&cd&{$path}&&&&git&reset&--hard&origin/master&&&&git&clean&-f&&&&git&pull&2&&1&&&&git&checkout&master&)【补充】:如何 clone git 项目到一个非空目录如果我们往一个非空的目录下 clone git 项目,就会提示错误信息:fatal: destination path &#39;.&#39; already exists and is not an empty directory.解决的办法是:1. 进入非空目录,假设是cd /workdir/proj12. git clone --no-checkout https://git.oschina.net/NextApp/platform.git tmp3. mv tmp/.git . & #将 tmp 目录下的 .git 目录移到当前目录4. rmdir tmp5. git reset --hard HEAD然后就可以进行各种正常操作了。【参考】:1、2、3、
版权所有。转载时必须以链接形式注明作者和及本声明。
上一篇:下一篇:
0条评论 “Gitlab或者GitHub利用webhook实现push时项目自动部署”
No Comment .
名称(*必填)
邮件(选填)
网站(选填)
记住我,下次回复时不用重新输入个人信息
Www.Piaoyi.Org 原创文章版权由所有Thinkphp3.2 行为扩展和插件(Hook)实例详解 - ThinkPHP框架
ThinkPHP3.2.2 行为(Behavior)扩展以及插件(Plug or Hook)详解(含实例)
行为(Behavior)是ThinkPHP扩展机制中比较关键的一项扩展,行为既可以独立调用,也可以绑定到某个标签中进行侦听,官方提出的CBD模式中行为也占了主要的地位,可见行为在ThinkPHP框架中意义非凡。
这里指的行为是一个比较抽象的概念,你可以想象成在应用执行过程中的一个动作或者处理,在框架的执行流程中,各个位置都可以有行为产生,例如路由检测是一个行为,静态缓存是一个行为,用户权限检测也是行为,大到业务逻辑,小到浏览器检测、多语言检测等等都可以当做是一个行为,甚至说你希望给你的网站用户的第一次访问弹出Hello,world!这些都可以看成是一种行为,行为的存在让你无需改动框架和应用,而在外围通过扩展或者配置来改变或者增加一些功能。
而不同的行为之间也具有位置共同性,比如,有些行为的作用位置都是在应用执行前,有些行为都是在模板输出之后,我们把这些行为发生作用的位置称之为标签(位),当应用程序运行到这个标签的时候,就会被拦截下来,统一执行相关的行为,类似于AOP编程中的“切面”的概念,给某一个切面绑定相关行为就成了一种类AOP编程的思想。(摘抄 :http://www.thinkphp.cn/info/249.html),对咯,如果你不懂”切面“这个概念,最好是先度娘下。
一、实例:(以下代码演示均基于 ThinkPHP3.2.2,未修改任何文件和目录结构),做一个ad(广告)的钩子
1.如果我们想在模板上调用例如{:tag(&#039;example&#039;,array(&#039;name&#039;=&&#039;name&#039;,&#039;value&#039;=&&#039;value&#039;))} 这样的方法,首先我们到 ThinkPHP-&Common-&functions.php,你会搜到 tag 这个方法,哈哈,我有强迫症,复制下 tag 方法,修改为function&hook($hook,$params=array()){
&&&&\Think\Hook::listen($hook,$params);&&&&&&&&//监听一个钩子
}2.在控制器中 Application-&Home-&Controller-&IndexController.class.php 添加如下代码:namespace&Home\C
use&Think\C
use&Think\H
class&IndexController&extends&Controller&{
&&&&public&function&index(){
&&&&&&&&Hook::add(&#039;ad&#039;,&#039;Behavior\\adBehavior&#039;);&//我种下一颗子,终于长出了果实(摘抄《小苹果》歌词)
&&&&&&&&$this-&display();
}空间命名,首次用不过还是挺好的,哈哈,已经暴露我是个小菜鸟了,教程可以结束了,洗洗睡吧!程序猿不能那么没有责任呀,做事情有始有终,想想还是继续的好,我是有多无聊和自己对话。
3.来新建一个行为取名叫ad(广告),ThinkPHP-&Library-&Behavior-&adBehavior.class.php&&&&namespace&B
&&&&class&adBehavior{
&&&&&&&&function&run($arg){
&&&&&&&&&&&&echo&&#039;我是一条&#039;.$arg[&#039;name&#039;].&#039;广告,&#039;.$arg[&#039;value&#039;].&#039;代言&#039;;&&&&&&&&//在此介绍下,run必须的&,细心的会在Think核心找到Behavior.class.php里面有这样一句操蛋的话&&abstract&public&function&run(&$params);&你懂的
&&&&}3.在模板中使用 Application-&Home-&View-&Index-&index.html 添加如下代码:&!DOCTYPE&html&PUBLIC&&-//W3C//DTD&XHTML&1.0&Transitional//EN&&&http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&&
&html&xmlns=&http://www.w3.org/1999/xhtml&&&
&&&&&title&ThinkPHP3.2.2&行为(Behavior)扩展以及插件(Plug&or&Hook)详解(含实例)
&&&&&meta&http-equiv=&Content-Type&&content=&text/&charset=utf-8&&/&
&&&&&meta&name=&description&&content=&Hook使用方法&&/&
&&&&&h1&How&to&used?&/h1&
&&&&{:hook(&#039;ad&#039;,&array(&#039;name&#039;=&&#039;AV&#039;,&#039;value&#039;=&&#039;*老师&#039;))}
&/html&哎呀,我的天又暴露本性了,少扯谈咯,纵观整个流程是操蛋的代码,每个控制器都需要去添加一个钩子,何谈机制。下面会介绍点好的,如果你看过 Onthink 或者 ThinkSNS 你会发现别人用得很流畅,此贴未完待续...
积分:1121
ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。

我要回帖

更多关于 什么是市场运行的实现机制 的文章

 

随机推荐