前一篇寫(xiě)了反射類(lèi)生成php速查表。過(guò)年了在家也沒(méi)事,想完成自己想要實(shí)現(xiàn)的sublime自動(dòng)完成文件生成。就是sublime里輸入關(guān)鍵字后按tab自動(dòng)補(bǔ)全一個(gè)全的函數(shù)名和參數(shù)的,按tab可以切換一致到最后的。也是給別人的承諾,今年肯定會(huì)實(shí)現(xiàn)sublime的tp5插件的。
地址在 https://github.com/yangweijie/SublimeThinkPHP5.0
"HTML_FILE_SUFFIX",
"TEMPLATE_NAME",
{ "trigger": "_ad", "contents": "protected function _after_delete(\\$data,\\$options) {\n ${1:}\n}$0" },
{ "trigger": "_af", "contents": "protected function _after_find(&\\$result,\\$options) {\n ${1:}\n}$0" },
{ "trigger": "_ai", "contents": "protected function _after_insert(\\$data,\\$options) {\n ${1:}\n}$0" },
{ "trigger": "_as", "contents": "protected function _after_select(&\\$result,\\$options){\n ${1:foreach(\\$result as &\\$record)\\{\n ${2:\\$this->_after_find(\\$record,\\$options);}\n \\}}\n}$0" },
{ "trigger": "_au", "contents": "protected function _after_update(\\$data,\\$options) {\n ${1:}\n}$0" },
{ "trigger": "_bi", "contents": "protected function _before_insert(&\\$data,\\$options) {\n ${1:}\n}$0" },
{ "trigger": "_bu", "contents": "protected function _before_update(&\\$data,\\$options) {\n ${1:}\n}$0" },
{ "trigger": "->_empty", "contents": "\\$this->_empty()$0" },
{ "trigger": "_get", "contents": "_get('${1:\\$name}')$0" },
{ "trigger": "_post", "contents": "_post('${1:\\$name}')$0" },
{ "trigger": "->_sql", "contents": "->_sql('${1:\\$name}')$0" },
{ "trigger": "->addAll", "contents": "->addAll(\\$${1:dataList},\\$${2:options},\\$${3:replace})$0" },
這個(gè)是寫(xiě)在Sublime的ThinkPHP 插件里 php.sublime-completions 文件里的。
completion 和snippet的區(qū)別在于 snippet只能一個(gè)文件一個(gè)補(bǔ)全。命令面版里有提示。
json 里直接字符串
$0
完成的最后光標(biāo)
tab 選中光標(biāo) ${1:XX}
1自增下標(biāo),: 選中的內(nèi)容
表示什么文本末按tab會(huì)觸發(fā)完成。
$ 換行之類(lèi)的要轉(zhuǎn)義
先上核心代碼:
<?php
namespace util;
class SnippetBuilder
{
public $cme;
public function __construct($classes)
{
// if (false == defined('THINK_VERSION')) {
// throw new \Exception('請(qǐng)?jiān)趖hinkphp應(yīng)用中執(zhí)行本類(lèi)', 1);
// }
$this->cme = new ClassMethodExtractor();
// $this->framework_type = version_compare(THINK_VERSION, '5') >= 0 ? 5 : 3;
$this->classes = $classes;
}
public function buildAll($path)
{
$consts = $this->getConsts();
$functions = $this->getFunctions();
$classes = $this->classes;
$this->ret = [];
if ($consts) {
$this->buildConsts($consts);
}
if ($functions) {
$this->buildFunction($functions);
}
if ($classes) {
foreach ($classes as $class) {
$class2 = $this->cme->getClassAnnotation(new \ReflectionClass($class));
$this->buildClass($class2);
}
}
if ($this->ret) {
file_put_contents($path, $this->parseAll($this->ret));
} else {
exit('沒(méi)有可生成的內(nèi)容');
}
}
// 獲取常量數(shù)組
public function getConsts()
{
$all_consts = get_defined_constants(true);
return array_keys($all_consts['user']);
}
// 生成常量完成
public function buildConsts($consts)
{
foreach ($consts as $key => &$const) {
$this->ret[] = $const;
}
}
// 生成類(lèi)的完成
public function buildClass($classes)
{
}
// 獲取定義的函數(shù)
public function getFunctions()
{
$arr = get_defined_functions();
$ret = [];
foreach ($arr['user'] as $key => $name) {
$foo = [];
$refFunc = new \ReflectionFunction($name);
$foo['args'] = $refFunc->getParameters();
$ret[$name] = $foo;
}
return $ret;
}
// 生成函數(shù)
public function buildFunction($functions)
{
}
}
// 獲取常量數(shù)組
public function getConsts()
{
$all_consts = get_defined_constants(true);
return array_keys($all_consts['user']);
}
php有函數(shù),且會(huì)區(qū)分core user 和擴(kuò)展的。我們只需要user定義,也就是tp框架定義的。
// 獲取定義的函數(shù)
public function getFunctions()
{
$arr = get_defined_functions();
$ret = [];
foreach ($arr['user'] as $key => $name) {
$foo = [];
$refFunc = new \ReflectionFunction($name);
$foo['args'] = $refFunc->getParameters();
$ret[$name] = $foo;
}
return $ret;
}
php也有個(gè)獲取全部函數(shù)名的方法。同樣只拿user
然后新的函數(shù)反射類(lèi) new \ReflectionFunction($name);
獲取它的參數(shù) $refFunc->getParameters();
$all_class = get_declared_classes();
這回沒(méi)有user好事了,不過(guò)可以反射類(lèi)isInternal區(qū)分。
// 獲取全部用戶定義的類(lèi)
public function getAllUserClasses(){
$all_class = get_declared_classes();
$ret = [];
foreach ($all_class as $class) {
$rf = new \ReflectionClass($class);
if(false == $rf->isInternal()){
if('app\index\controller\Index' == $class){
continue;
}
$ret[] = $class;
}
}
return $ret;
}
if ($classes) {
foreach ($classes as $class) {
$class2 = $this->cme->getClassAnnotation(new \ReflectionClass($class));
$this->buildClass($class2);
}
}
用cme類(lèi)提取出類(lèi)和對(duì)應(yīng)方法及參數(shù)。
我寫(xiě)了 SublimeSnippetBuilder來(lái)繼承我之前的 SnippetBuilder,因?yàn)槲蚁胱龅氖撬形谋揪庉嬈鞯耐瓿缮伞O燃軜?gòu)好結(jié)構(gòu),以后慢慢填坑。
先整體代碼:
<?php
namespace util;
class SublimeSnippetBuilder extends SnippetBuilder
{
// 生成函數(shù)
public function buildFunction($functions)
{
foreach ($functions as $name => $fun) {
$args_arr = [$name, '(', ')'];
if ($fun['args']) {
$args_arr = [$name, '('];
$index = 1;
foreach ($fun['args'] as $key => $arg) {
$p = new \ReflectionParameter($name, $key);
if ($p->isPassedByReference()) {
$arg_str_new = '\&\\$' . $p->getName();
} else {
$arg_str_new = '\\$' . $p->getName();
}
if ($p->isOptional() && $p->isDefaultValueAvailable()) {
// 獲取某些內(nèi)部類(lèi)的參數(shù)會(huì)拋異常,且異常時(shí)$class會(huì)變化不是我們想知道的哪個(gè)類(lèi)方法一場(chǎng)了
try {
$defaul = $p->getDefaultValue();
$arg_str_new .= is_array($defaul) ? ' = []' : ' = ' . var_export($defaul, 1);
} catch (\Exception $e) {
trace($p->isVariadic());
trace($name . '_' . $key);
}
}
if ($index == 1) {
$p_str = sprintf('${%d:%s}', $index, $arg_str_new);
} else {
$p_str = sprintf('${%d: ,%s}', $index, $arg_str_new);
}
$args_arr[] = $p_str;
$index++;
}
$args_arr[] = ')';
}
$contens = implode('', $args_arr) . '$0';
$foo = [
'trigger' => $name,
'contents' => $contens,
];
$this->ret[] = $foo;
}
}
public function buildClass($class)
{
if($class['methods']){
foreach ($class['methods'] as $name => $fun) {
switch ($fun['type']) {
case 'public_static':
case 'private_static':
$trigger_name = "::{$name}";
break;
case 'public_public':
case 'private_public':
$trigger_name = "->{$name}";
break;
default:
$trigger_name = '';
break;
}
$args_arr = [$trigger_name, '(', ')'];
if (empty($fun['args']) == false) {
$args_arr = [$trigger_name, '('];
$index = 1;
foreach ($fun['args'] as $key => $p) {
if ($p->isPassedByReference()) {
$arg_str_new = '\&\\$' . $p->getName();
} else {
$arg_str_new = '\\$' . $p->getName();
}
if ($p->isOptional() && $p->isDefaultValueAvailable()) {
// 獲取某些內(nèi)部類(lèi)的參數(shù)會(huì)拋異常,且異常時(shí)$class會(huì)變化不是我們想知道的哪個(gè)類(lèi)方法一場(chǎng)了
try {
$defaul = $p->getDefaultValue();
$arg_str_new .= is_array($defaul) ? ' = []' : ' = ' . var_export($defaul, 1);
} catch (\Exception $e) {
trace($p->isVariadic());
trace($name . '_' . $key);
}
}
if ($index == 1) {
$p_str = sprintf('${%d:%s}', $index, $arg_str_new);
} else {
$p_str = sprintf('${%d: ,%s}', $index, $arg_str_new);
}
$args_arr[] = $p_str;
$index++;
}
$args_arr[] = ')';
}
$contens = implode('', $args_arr) . '$0';
$foo = [
'trigger' => $trigger_name,
'contents' => $contens,
];
$this->ret[] = $foo;
}
}
}
public function parseAll($ret)
{
// dump($ret);
$ret = [
"scope" => "source.php - variable.other.php",
"completions" => $ret,
];
return json_encode($ret, JSON_PRETTY_PRINT);
}
}
其實(shí) 就是生成對(duì)應(yīng)的多維數(shù)組,數(shù)字索引為常量,函數(shù)方法為多維數(shù)組。
函數(shù)的trigger就是函數(shù)名,類(lèi)無(wú)非::
、->
后跟方法名
然后區(qū)分代參不帶參,帶參再遍歷參數(shù),區(qū)分引用和默認(rèn)值的情況。用了sprintf 方法拼接${index:content} 這種格式。
最終生成json,用了JSON_PRETTY_PRINT 格式化輸出后寫(xiě)文件。
整體思路還是很清晰的。
其他語(yǔ)言的可以借鑒。
效果:
一下子兩千行,手寫(xiě)得累死。
其實(shí),大家只需擴(kuò)展getAllUserClasses 就可以生成其他類(lèi)的,比如swoole的。
題外話,新插件提交wbond 開(kāi)始用branch 結(jié)果不推薦了要tag。我折騰了幾次才通過(guò)ci。人家不高興了。不給我過(guò),有能力的直接git clone吧。視圖那沒(méi)找到規(guī)律先手寫(xiě)的。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
新聞名稱(chēng):php類(lèi)庫(kù)到sublime完成-創(chuàng)新互聯(lián)
標(biāo)題來(lái)源:http://aaarwkj.com/article40/gjhho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、定制網(wǎng)站、網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、App開(kāi)發(fā)、網(wǎng)站營(yíng)銷(xiāo)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容