《PHP學習:利用php-cli和任務計劃實現刷新token功能的方法》要點:
本文介紹了PHP學習:利用php-cli和任務計劃實現刷新token功能的方法,希望對您有用。如果有疑問,可以聯系我們。
1、業務需求PHP編程
需要實現這樣一個功能:在第三方授權的認證當中,在用戶首次登錄授權我們會得到一個access_token,有效期為25小時,還會得到一個refresh_token,有效期為30天.PHP編程
我們只要保存好這個refresh_token,在30天內我們都可以用這個refresh_token去請求一個api,他會返回一個新的access_token.這樣我們只需要讓用戶授權一次,我們就可以獲得長達30天的一個授權期限.PHP編程
這里可以分為幾個點:PHP編程
<1>這個應該是要定期執行的一個任務.PHP編程
25小時才會過期,那么我們12小時刷一次就足夠了,并不需要很頻繁的刷新.假設這樣一種情況:讓一個頁面持續的運行,用一個while的死循環去執行一個任務,執行完之后sleep很長一段時間,然后再繼續執行.這樣做也是可以的,但是比較占資源.他執行的時間很少,等待的時間卻很長,沒必要這樣一直等待.PHP編程
<2>這個應該不需要是一個可以訪問到的頁面.PHP編程
是我們內部執行的一個任務,不需要是人人可以訪問到的一個頁面.PHP編程
<3>這個頁面應該也要和框架融合在一起,可以訪問到各種資源.PHP編程
一個普通的php頁面恐怕是不行的,我們需要跟框架融合的一個頁面,需要可以訪問到各種資源,比如說redis,比如說config,等等.PHP編程
2、用cli模式運行codeigniter的頁面PHP編程
<1>cli的頁面特性PHP編程
什么是cli模式?就是命令行模式.我們可以不用url來訪問php頁面,而使用命令行來訪問,這是可以的.PHP編程
對頁面來說,什么都不需要改變,比如:PHP編程
>同樣要是一個普通的controller,要繼承自CI_Controller;PHP編程
>要定義路由器,這個頁面必須也是經由路由訪問得到;PHP編程
>甚至仍然可以添加這樣的聲明PHP編程
defined('BASEPATH') OR exit('No direct script access allowed');PHP編程
>可以通過添加一個判斷讓頁面只能讓cli訪問:
PHP編程
public function __construct() { parent::__construct(); if (!is_cli()) exit("不正確的訪問方式"); }
>通過echo打印在命令行上面,就如打印在頁面上一樣PHP編程
<2>怎么通過命令行訪問PHP編程
cd E:\xxx\xxx\phpSite? //網站的根目錄,即index.php所在目錄PHP編程
php index.php aaa bbb ccc? //即訪問網址為yourdomain.com/index.php/aaa/bbb/ccc這樣的地址注意:PHP編程
>第一行是轉到網站根目錄這個路徑;PHP編程
>第二行php是調用了php.exe這個是因為我們有設置php的環境變量;PHP編程
>index.php不可以缺少,因為這里我們沒有走服務器了,沒有經過服務器的url-rewrite,所以這個index.php是必不可少的.PHP編程
我們可以將這兩行代碼放在一個文本文件里面,將名字改為refresh.bat,雙擊這個bat文件,他就會執行一次,相當于打開命令行來執行PHP編程
如果我們需要調試的話,不要讓彈出的命令行自動關掉,我們可以在加上第三行代碼,加一個單詞就可以了:pausePHP編程
他就會停住并且顯示相關的信息方便我們調試.PHP編程
<3>頁面調試PHP編程
如下例子,此頁面通過把一個值每刷新頁面一次累加一次,存在redis里,來驗證頁面是否有被訪問過:PHP編程
<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * Created by PhpStorm. * Date: 2017/2/20 * Time: 23:18 */ class Refresh_token extends CI_Controller { public function __construct() { parent::__construct(); if (!is_cli()) exit("不正確的訪問方式"); } public function index() { $oldData = $this->redis_model->get_access_token('1234'); if ($oldData == null) $oldData = 0; $newData = $oldData + 1; $this->redis_model->set_access_token('1234',$newData); echo 'its refresh_token page!'; } }
3、創建計劃任務讓他運行bat文件
PHP編程
PHP編程
PHP編程
PHP編程
PHP編程
4、刷新tokenPHP編程
<1>命名的規則PHP編程
刷新token首先想到的是遍歷redis.redis那么多應該怎么遍歷?我想到的是給不同類型redis設定不同的前綴.PHP編程
比如說,所有用戶的refresh_token的key都這樣寫:"refresh_token_用戶id".然后用redis的模式匹配就可以把以"refresh_token_"開頭的key找出來,然后一條條處理.PHP編程
<2>redis遍歷PHP編程
首先,redis是有模式識別的功能,參見手冊:https://redis.io/commands/keysPHP編程
其次,php原生的redis組件是有這個模式識別的功能.原生的用法大概是這樣:PHP編程
// 原生redis類庫,不需要config/redis.php $redis = new Redis(); $redis->connect('127.0.0.1',6379); //$redis->set('key10','xx10',20);//第三個參數是存續時間,單位是秒,如果不填則為永久 echo $redis->get('key10');
大致說一下,ci框架的redis操作api呢是在php原生的api上面進行了一層封裝,而他這個封裝呢不包括這個模式識別.PHP編程
本人的自定義操作api是從框架api直接拷貝過來的,也是為了方便添加更多方法.在原生的框架上面添加總歸不太好,比如說將來要升級、移植等問題.寫成自己的類庫想怎么改怎么改.PHP編程
下面是添加這個模式識別api:PHP編程
public function keys($pattern) { return $this->_redis->keys($pattern); }
然后在model里面這樣調用:PHP編程
public function get_keys($pattern) { return $this->rediscli->default->keys($pattern); }
然后在controller里面使用:PHP編程
// $this->redis_model->set_redis('hello'.'1','my_hello_1',12345); // $this->redis_model->set_redis('hello'.'2','my_hello_2',12345); // $this->redis_model->set_redis('hello'.'3','my_hello_3',12345); $vals = $this->redis_model->get_keys('hello'.'*'); if ($vals != null)//注意這里,他是一個array,如果返回的是匹配到0個,那么不會是一個空的有效的0長度的array,而確實是一個null. { foreach ($vals as $val) { echo '</br>'; echo $val; } }
這樣就可以完成對特定前綴的遍歷了! PHP編程
注意:這里要特別說明一下,我們在寫入這個token的時候,會將有效期寫進去,那么只要這個有效期的值是正確的,我們取到這個token必定是有效的,那么我們拿這個有效的token去刷新,必然是成功的.一般不存在刷新失敗的情況.因為這個token一旦失效我們也就取不到了.PHP編程
以上這篇利用php-cli和任務計劃實現刷新token功能的方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持維易PHP.PHP編程