鍍金池/ 問(wèn)答/ PHP問(wèn)答
舊言 回答

個(gè)人觀點(diǎn):不推薦,在case后面做公式,直接case單一的值就好。
為什么不推薦? 、、邋遢。

switch( $search ) {
    case 'like':
        $key.=' like';
        $this->_datas[$key] = '%' . $value . '%';
        break;
    case 'greater':
        $key.=' >=';
        $value = strtotime( $value );
        $this->_datas[$key] = $value;
        break;
    case 'less':
        $key.=' <=';
        $value = strtotime( $value . " +1 day" );
        $this->_datas[$key] = $value;
        break;
    case 'lessthan':
        $key .= ' <=';
        $value = strtotime($value);
        $this->_datas[$key] = $value;
        break;
    case 'big':
        $key.=' >';
        $this->_datas[$key] = $value;
        break;
    case 'small':
        $key.=' <';
        $this->_datas[$key] = $value;
        break;
    case 'in':
        $key.=' in';
        $this->_datas[$key] = '(' . implode( ',', $value ) . ')';
        break;
    case 'notequal':
        $key.=' <>';
        $this->_datas[$key] = $value;
        break;
    case 'noteq':
        $key.=' !=';
        $this->_datas[$key] = $value;
        break;
    default:
        $this->_datas[$key] = $value;
}

如果case下面拼裝sql的代碼一致,可以這樣寫:

case 'big':
case 'small':
case 'noteq':
    $this->_datas[$key] = $value;
陌上花 回答

這樣的鏈接后面一般都有一次性的Token,后臺(tái)驗(yàn)證后自動(dòng)設(shè)置為登錄狀態(tài),也有相應(yīng)的cookies設(shè)置。鏈接大概是這樣子的。
https://www.thesite.com/index?token=a6sd6afs68a8sd78a&otherparams...

葬憶 回答

對(duì)于參數(shù)綁定為何可以避免SQL注入,建議題主可以了解一下,值得注意的是prepare語(yǔ)句只能解析一條SQL,下面摘要說(shuō)明一下prepare的作用:
首先從mysql服務(wù)器執(zhí)行sql的過(guò)程開始講起,SQL執(zhí)行過(guò)程包括以下階段 詞法分析->語(yǔ)法分析->語(yǔ)義分析->執(zhí)行計(jì)劃優(yōu)化->執(zhí)行。詞法分析->語(yǔ)法分析這兩個(gè)階段我們稱之為硬解析。詞法分析識(shí)別sql中每個(gè)詞,語(yǔ)法分析解析SQL語(yǔ)句是否符合sql語(yǔ)法,并得到一棵語(yǔ)法樹(Lex)。對(duì)于只是參數(shù)不同,其他均相同的sql,它們執(zhí)行時(shí)間不同但硬解析的時(shí)間是相同的。而同一SQL隨著查詢數(shù)據(jù)的變化,多次查詢執(zhí)行時(shí)間可能不同,但硬解析的時(shí)間是不變的。對(duì)于sql執(zhí)行時(shí)間較短,sql硬解析的時(shí)間占總執(zhí)行時(shí)間的比率越高。而對(duì)于淘寶應(yīng)用的絕大多數(shù)事務(wù)型SQL,查詢都會(huì)走索引,執(zhí)行時(shí)間都比較短。因此淘寶應(yīng)用db sql硬解析占的比重較大。

Prepare的出現(xiàn)就是為了優(yōu)化硬解析的問(wèn)題。Prepare在服務(wù)器端的執(zhí)行過(guò)程如下

1) Prepare 接收客戶端帶”?”的sql, 硬解析得到語(yǔ)法樹(stmt->Lex), 緩存在線程所在的preparestatement cache中。此cache是一個(gè)HASH MAP. Key為stmt->id. 然后返回客戶端stmt->id等信息。

2) Execute 接收客戶端stmt->id和參數(shù)等信息。注意這里客戶端不需要再發(fā)sql過(guò)來(lái)。服務(wù)器根據(jù)stmt->id在preparestatement cache中查找得到硬解析后的stmt, 并設(shè)置參數(shù),就可以繼續(xù)后面的優(yōu)化和執(zhí)行了。

Prepare在execute階段可以節(jié)省硬解析的時(shí)間。如果sql只執(zhí)行一次,且以prepare的方式執(zhí)行,那么sql執(zhí)行需兩次與服務(wù)器交互(Prepare和execute), 而以普通(非prepare)方式,只需要一次交互。這樣使用prepare帶來(lái)額外的網(wǎng)絡(luò)開銷,可能得不償失。我們?cè)賮?lái)看同一sql執(zhí)行多次的情況,比如以prepare方式執(zhí)行10次,那么只需要一次硬解析。這時(shí)候  額外的網(wǎng)絡(luò)開銷就顯得微乎其微了。因此prepare適用于頻繁執(zhí)行的SQL。

Prepare的另一個(gè)作用是防止sql注入,不過(guò)這個(gè)是在客戶端jdbc通過(guò)轉(zhuǎn)義實(shí)現(xiàn)的,跟服務(wù)器沒(méi)有關(guān)系。 

建議題主看下MySQL官方文檔(https://dev.mysql.com/doc/ref...)。什么?看不懂英文?試試百度翻譯吧:https://fanyi.baidu.com

clipboard.png

瘋浪 回答

client_id是你這個(gè)應(yīng)用在oAuth2網(wǎng)站注冊(cè)的應(yīng)用獲得的。

比如騰訊吧,雖然騰訊不一定是密碼模式,但是這里舉個(gè)例子。

如果你是一個(gè)A網(wǎng)站,需要獲取用戶在騰訊的賬戶信息,那么你需要在騰訊注冊(cè)你的應(yīng)用,獲取你的client_id。
這樣在認(rèn)證的時(shí)候,騰訊的OAuth就可以區(qū)分這個(gè)用戶授權(quán)了哪些應(yīng)用(你的A網(wǎng)站或者別人的B網(wǎng)站)。

A網(wǎng)站和B網(wǎng)站都有各自的client_id,騰訊根據(jù)這個(gè)id來(lái)區(qū)分用戶給予的授權(quán)

當(dāng)然了,為了防止偽造,還會(huì)另外有一個(gè)clinet_secret用于確認(rèn)你使用的client_id確實(shí)是你這個(gè)網(wǎng)站所持有的。

還有你所不理解的幾個(gè)參與者。
還是以上面的例子解釋。

  • 用戶 是騰訊的用戶,A網(wǎng)站或者B網(wǎng)站需要用戶的授權(quán)來(lái)獲取用戶的騰訊賬戶的信息。
  • 第三方客戶端 就是A網(wǎng)站或者B網(wǎng)站的手機(jī)APP(網(wǎng)頁(yè))之類的。
  • 授權(quán)服務(wù)端 就是指騰訊啦
  • 客戶端 就是指A網(wǎng)站或者B網(wǎng)站的服務(wù)器

至于為什么要分成第三方客戶端客戶端,這個(gè)主要是為了secret_id保密,如果你的secret_id直接寫在用戶應(yīng)用當(dāng)中,那么誰(shuí)都可以用你的A網(wǎng)站的身份去獲取用戶的信息了。所以secret_id只能保存在后臺(tái)。

所以在這里可以理解成客戶端就是指A網(wǎng)站的服務(wù)器,在面對(duì)騰訊的Oauth授權(quán)的情況下,騰訊是授權(quán)服務(wù)端,A網(wǎng)站后臺(tái)是授權(quán)的客戶端。


暫時(shí)就寫這么點(diǎn),有說(shuō)錯(cuò)或者還有不理解的話后面再補(bǔ)充

兔囡囡 回答

解決了,刪除指定包然后重新 require 一次
估計(jì)是開始時(shí)用的源不同導(dǎo)致的沖突出現(xiàn)的問(wèn)題

涼心人 回答

如果你們是需要發(fā)送短信。這個(gè)一般沒(méi)有直接使用CMPP協(xié)議對(duì)接的。
像阿里大魚的短信,也是走的http協(xié)議。你可能走入了誤區(qū)了。

兮顏 回答

你好,請(qǐng)問(wèn)rules里的validator可以和async-validator結(jié)合起來(lái)嗎?難道得一個(gè)的寫驗(yàn)證器

雨蝶 回答

找到問(wèn)題所在了,xml格式的數(shù)據(jù)標(biāo)簽里面不能含有任何空格,去掉就好了,好坑啊,之前一直是json通訊,第一次接觸xml采坑了

看了一下報(bào)錯(cuò),是window socket 的問(wèn)題,我記得我是前幾天開了虛擬機(jī)設(shè)置網(wǎng)卡的問(wèn)題,然后就在命令行里重置了一下。重啟就好了!

葬憶 回答

你已經(jīng)在 app.js 里示例化過(guò) Vue 了,為什么還要在 balde 模板里再次進(jìn)行示例化呢?

直接在 blade 模板中引入編譯后的 app.js,就可以使用 Vux 提供的組件了

PS: Vue 是個(gè)好框架 :)

離觴 回答

找不到相關(guān)文件? opencart 是開源免費(fèi)的商城, 可以看到源代碼的,讀懂購(gòu)物流程就行

厭惡我 回答

不用開啟服務(wù)器配置,通過(guò)兩步來(lái)獲取open_id,第一步先通過(guò)appid和secret獲取access_token,第二步用access_token來(lái)獲取open_id。

鐧簞噯 回答
if(in_array($nowSelf,['/news.php','/newsview.php','/help.php']))
{
    //code
}

任何電腦都可以
php有自帶的調(diào)試服務(wù)器,運(yùn)行以下命令:
php -S 0.0.0.0

薔薇花 回答

json_encode轉(zhuǎn)換成json字符串

小眼睛 回答

謝邀!

  1. 對(duì)隨機(jī)的五位數(shù)排序,最小在前最大在后的依次增大
  2. 前4次是隨機(jī)值
  3. 第5次是總數(shù)減去前四次隨機(jī)值
  4. 重要的就是前四次隨機(jī)值的范圍,就是其中的最小值和最大值。這時(shí)候如果最小值和最大值限制越多到后面越容易產(chǎn)生隨機(jī)值,并且要保證最小值要大于前一個(gè)隨機(jī)值的100以上。而關(guān)于最大值就簡(jiǎn)單多了,盡可能小,但是不會(huì)比最小值小。并且不會(huì)比我下面例子中使用的最大值( $rand_max )大。(至于為什么你可以思考下)
  5. 如果產(chǎn)生的隨機(jī)值中差值產(chǎn)生重復(fù),那么就重新產(chǎn)生隨機(jī)值
    <?php
    
    $sum  = 10000;
    $diff = 100;
    $count = 5;
    
    $return = array();
    $min    = 0;
    $i         = 1; 
    while($i < $count) {
    
        // 隨機(jī)數(shù)不符合要求時(shí)的結(jié)果初始化
        if(isset($return[$i]) || isset($return[$i+1])) {
            unset($return[$i]);
            unset($return[$i+1]);
        }
    
        // 剩余數(shù)
        $remain_sum = $sum - array_sum($return);
        // 剩余需要隨機(jī)的個(gè)數(shù)
        $remain_count = intval($count - count($return));
        // 高斯求最小差值和,分兩部分:S = n(n+1)(2n+4)/12 + $diff * ((n-1)(n-2)/2)
        $min_diff = $remain_count * ($remain_count - 1) * (2 * ($remain_count - 1) + 4) / 12 + ($remain_count * ($remain_count - 1) / 2) * $diff;
        // 隨機(jī)范圍的最小值
        $min = $i == 1 ? 1 : $return[$i-1] + $diff + 1;
        
        // 在范圍內(nèi)獲取隨機(jī)數(shù)
        mt_srand((double)microtime() * 1000000);
        // 隨機(jī)范圍的最大值
        $rand_max   = intval(($remain_sum - $min_diff) / $remain_count);
        // 產(chǎn)生隨機(jī)數(shù)
        $min        = mt_rand($min, $rand_max);
        // 放入返回的數(shù)組
        $return[$i] = $min;
        if($i == $count - 1) {
            // 最后一個(gè)隨機(jī)數(shù)直接取總數(shù)減去前面的隨機(jī)數(shù)
            $return[$i+1] = $remain_sum - $min;
        }
        
        if(check_diff($return) === false) {
            $i--;
            continue;
        }
    
        $i++;
    }
    
    var_dump($return);die;
    
    // 判斷數(shù)組內(nèi)是否有差值相等
    function check_diff($arr) {
        if(empty($arr)) {
            return false;
        }
        
        $arr = array_map('intval', $arr);
        sort($arr);
        
        $count = count($arr);
        $diff_arr = array();
        for($i = $count - 1; $i >= 0; $i --) {
            for ($j = 0; $j < $count; $j ++) {
                if($arr[$i] <= $arr[$j]) {
                    continue 2;
                }
                $diff_arr[] = $arr[$i] - $arr[$j];
            }    
        }
        
        if(count($diff_arr) === count(array_unique($diff_arr))) {
            return true;
        }
        
        return false;
    }
旖襯 回答

你只是想返回一個(gè)結(jié)果,但使用 throw 一般是拋出異常。
很多時(shí)候返回 status 為0,其實(shí)并不是異常。
我覺(jué)得這些時(shí)候使用 throw 是不合適的。
所謂的異常,應(yīng)該是“它本來(lái)應(yīng)該是這樣的,但結(jié)果卻不是”,才需要拋出異常。
比如你要處理一張圖片,傳的參數(shù)指向的文件存在,文件后綴也存在,但讀取數(shù)據(jù)后卻不能正確處理,這時(shí)拋個(gè)異常是可以理解的,但我個(gè)人覺(jué)得這還不夠好。

因?yàn)槲揖陀龅竭^(guò),使用 thinkPHP 3.2 的圖片處理類,遇到不能處理的圖片,直接拋出了異常,但其實(shí)對(duì)我來(lái)說(shuō),如果處理圖片有問(wèn)題 ,是可以直接跳過(guò)去的。

也就是說(shuō):只有“這一步如果出錯(cuò),后面的代碼執(zhí)行就完全沒(méi)有意義或者完全不能執(zhí)行”的時(shí)候才去拋出異常,否則只需要返回結(jié)果,給使用者(可能是控制器)去處理就好了。

對(duì)于樓主的需求,ThinkPHP 是有內(nèi)置的方法的,比如控制器中有 success() 和 error() 兩種方法來(lái)滿足樓主的需要,當(dāng)然,我個(gè)人比較喜歡 ThinkPHP 3.2的處理方式,比如簡(jiǎn)潔,ThinkPHP 5中的這兩個(gè)方法添加了不必要的參數(shù),寫起來(lái)倒挺麻煩的。
但這兩個(gè)方法只在控制器中有,模型中默認(rèn)是沒(méi)有的,當(dāng)然,如果你喜歡的話,也可以加到模型中去。
但我個(gè)人同樣不太推薦。處理返回結(jié)果或頁(yè)面跳轉(zhuǎn)的任務(wù)還是交給控制器會(huì)比較好。

模型中,其實(shí)可以自己定義個(gè)類似的方法,比如:

function succ($data="",$status=1){
      return array(
       'status'=>$status,
       'info'=>$data,
    );
}

function error($msg=""){
  return succ($msg,0);
}

你在模型中直接 return succ($data);或 return error($msg);即可。

控制器中根據(jù)返回的數(shù)組,再使用$this->success()或$this->error();當(dāng)然,如果你在使用ThinkPHP 5,也像我一樣比較喜歡 ThinkPHP 3.2 的風(fēng)格,這兩個(gè)方法你是可以改成3.2的風(fēng)格的。

說(shuō)回樓主和你看到的大神的代碼,基本思想都差不多,只不過(guò)你直接返回一個(gè)數(shù)組,而“大神”卻直接拋出異常,我不喜歡這位大神的風(fēng)格。
但你和“大神”都喜歡寫重復(fù)的 "status'=>1,"msg"=>......,我則比較喜歡把它裝進(jìn)函數(shù)或方法中,畢竟這兩個(gè)操作是使用非常頻繁的。

關(guān)于代碼中較多 if/else 的情況,我一般使用兩種方法解決:

  1. 短的判斷可以用三目運(yùn)算符代替;
  2. 很多時(shí)候 if 時(shí)使用了return ,后面就可以不寫 else 了 。

補(bǔ)充:

概括一下:

  1. 模型中建議使用 return ,而不是拋出異常,return 的數(shù)據(jù)可以自己封裝個(gè)函數(shù)或方法;(當(dāng)然,要結(jié)合業(yè)務(wù)的具體需求!)
  2. 拋出異常意味著程序的終止,在非必須的情況下不要這樣做;
  3. 控制器中直接使用 success 和 error 或 ajaxReturn 方法即可。

但如果把樓主看到的“大神”的代碼從模型中移到控制器的話,應(yīng)該是合理的(除了重復(fù)的代碼有點(diǎn)多外)。
我個(gè)人是不太喜歡使用 throw,但我查看了一下 ThinkPHP 5 和 ThinkPHP 3.2 的源碼,其中的 success和 error 方法除了使用參數(shù)復(fù)雜性不同外,還有一點(diǎn)區(qū)別就是 3.2直接使用 exit()結(jié)束程序,而 5.0 版本中使用的是 throw 一個(gè)異常類。

應(yīng)該有理由相信,使用 throw 可能會(huì)比如說(shuō) exit 更好。
于是,我找到一種說(shuō)法:

PHP調(diào)用exit退出腳本執(zhí)行不會(huì)導(dǎo)致PHP服務(wù)退出。
https://segmentfault.com/q/10...

我不了解底層的機(jī)制,但我覺(jué)得這種說(shuō)法是比較可信的。

不將就 回答

useEslint: false,

在config中獎(jiǎng)useEslint設(shè)置為false,代碼就不會(huì)強(qiáng)制檢測(cè)代碼格式了

朽鹿 回答

上nginx,可以設(shè)置servername解決。