你的網站忽略了主動推送嗎?Behavior行爲擴展

這是我2017年的開篇,也是我在Segmentfault的第一篇文章,寫的很差還請多多包涵,我是一位碼農,在segmentfault獲得本身的一塊小田地,喜歡這裏的歸屬感,我願意天天在這塊地裏勞做,記錄個人學習、工做、生活中的珍貴點滴。javascript

如下信息根據您的興趣推薦:php

王思聰4200萬生日趴豪奢曝光,香檳王灌到飽。
臺灣康師傅宣佈解散,大陸業務營運不受影響。
「五福事件」再次來襲!網友評論:馬雲,看來你是沒被罵夠!java

天天新聞咋這麼多,刷的停不下來都沒時間工做了。(旁白君:喂喂,打住,你好像跑偏了!),想一想天天網絡信息流如此巨大,若是網站不及時把原創好文章推送給搜索引擎,基本就會埋沒在信息流中。(旁白君:好像是那麼回事!)thinkphp

使用主動推送功能會達到怎樣效果

及時發現:能夠縮短百度爬蟲發現您站點新連接的時間,使新發布的頁面能夠在第一時間被百度收錄。編程

保護原創:對於網站的最新原創內容,使用主動推送功能能夠快速通知到百度,使內容能夠在轉發以前被百度發現。segmentfault

(旁白君:有沒有這麼厲害哦?)api

信不信看官方介紹:百度站長平臺推送介紹網絡

ThinkPHP行爲擴展

行爲(Behavior)是一個比較抽象的概念,相似於AOP編程中的「切面」的概念,給某一個切面綁定相關行爲就成了一種類AOP編程的思想。(旁白君:AOP又是什麼?),熟悉Java的朋友應該對AOP不陌生:app

在運行時,動態地將代碼切入到類指定的方法、位置上,這種編程思想就是面向切面的編程。直白的說:在不修改原代碼的狀況下,給指定方法添加新功能。框架

ThinkPHP提供標籤位置有如下(按照執行順序排列):

標籤 描述
app_init 應用初始化標籤位
path_info PATH_INFO檢測標籤位
app_begin 應用開始標籤位
action_name 操做方法名標籤位
action_begin 控制器開始標籤位
view_begin 視圖輸出開始標籤位
view_parse 視圖解析標籤位
template_filter 模板內容解析標籤位
view_filter 視圖輸出過濾標籤位
view_end 視圖輸出結束標籤位
action_end 控制器結束標籤位
app_end 應用結束標籤位

(旁白君:標題黨嗎?我只想知道怎麼作才能夠推送給百度收錄!)

別急會招式還得有內功,你們都知道ThinkPHP是一個很好的開發框架,ThinkCMF是一款基於ThinkPHP+MySQL開發的中文內容管理框架,此文是針對ThinkCMF開發的行爲擴展,固然基於ThinkPHP開發的全部內容管理系統簡單修改下也可通用。

ThinkCMF後臺分析

ThinkCMF後臺文章管理文件:application/Portal/Controller/AdminPostController.class.php,此文件裏面有4個方法是須要擴展的:

方法名稱 描述
add_post 文章添加提交
edit_post 文章編輯提交
delete 文章刪除(軟刪除)
restore 文章還原(回收站恢復)

當以上4各方法執行完畢時,須要添加主動推送代碼,因此是要擴展action_end (控制器結束)標籤位。

一切從代碼開始

一、在任意地方新建php文件:BaiduLinkSubmitBehavior.class.php代碼以下:

<?php
namespace Common\Behavior;
use Think\Behavior;
/**
 * 百度站長平臺主動推送行爲擴展
 * 做者:許劍鋒
 * 博客:https://segmentfault.com/u/xuebai
 * 准入密鑰獲取地址: http://zhanzhang.baidu.com/linksubmit/index?site=
 */
class BaiduLinkSubmitBehavior extends Behavior{

    // 在站長平臺驗證的站點,好比www.example.com
    const site = "www.example.com";
    // 在站長平臺申請的推送用的准入密鑰
    const token = "aaabbbccc";
    // 主動推送
    const api_urls = 'http://data.zz.baidu.com/urls';
    // 更新連接
    const api_update = 'http://data.zz.baidu.com/update';
    // 刪除連接
    const api_del = 'http://data.zz.baidu.com/del';

    //CURL封裝(默認:主動推送)
    private function _curl( $api_url, $urls = array() ) {
        if( empty($urls) || empty($api_url) ) {
            return false;
        }
        // api推送地址
        $api = $api_url . '?site=' . (self::site) . '&token=' . (self::token);
        $ch = curl_init();
        $options =  array(
            CURLOPT_URL             => $api,
            CURLOPT_POST            => true,
            CURLOPT_RETURNTRANSFER  => true,
            CURLOPT_POSTFIELDS      => implode("\n", $urls),
            CURLOPT_HTTPHEADER      => array('Content-Type: text/plain'),
        );
        curl_setopt_array($ch, $options);
        $result = curl_exec($ch);
        return $result;
    }

    // 主動推送
    private function _urls( $urls = array() ) {
        return $this->_curl( self::api_urls, $urls );
    }

    // 更新連接
    private function _update( $urls = array() ) {
        return $this->_curl( self::api_update, $urls );
    }

    // 刪除連接
    private function _del( $urls = array() ) {
        return $this->_curl( self::api_del, $urls );
    }

    // 行爲擴展的執行入口必須是run
    public function run(&$params) {
        // debug模式最好不推送連接
        if( APP_DEBUG ) {
            return ;
        }
        // 獲取模塊名稱(例如:portal)
        $module_name = strtolower(MODULE_NAME);
        // 獲取控制器名稱(例如:Adminpost)
        $controller_name = strtolower(CONTROLLER_NAME);
        // 獲取操做名稱(例如:add_post)
        $action_name = strtolower(ACTION_NAME);
        // 獲取當前對象的相關信息
        $reflector = new \ReflectionObject( $this );
        // 按照駝峯命名拼接函數名(例如:portalAdminpostAdd_post)
        $method_name = $module_name . ucfirst($controller_name) . ucfirst($action_name);
        // 若是當前類對象存在某個方法
        if( $reflector->hasMethod( $method_name ) ) {
            // getMethod() 返回 ReflectionMethod 對象
            $method = $reflector->getMethod( $method_name );
            // 執行當前對象的某個方法
            $method->invoke( $this );
        }
    }

    // 添加文章
    public function portalAdminpostAdd_post() {
        // 查詢最新的文章
        $posts_model = M( 'Posts' );
        $article = $posts_model
            ->alias("a")
            ->field('a.*,b.term_id')
            ->join("__TERM_RELATIONSHIPS__ b ON a.id = b.object_id", 'LEFT')
            ->order( 'a.id DESC' )->limit(1)->find();
        if( !empty($article)
            && !empty($article['id'])
            && !empty($article['term_id']) ) {
            // 經過post_id獲取文章url
            $url = leuu( 'article/index', array( 'id'=>$article['id'], 'cid'=>$article['term_id'] ), true, true );
            die( "add_post: {$url}" );
//            $res = $this->_urls( array( $url ) );
        }
    }

    // 編輯文章
    public function portalAdminpostEdit_post() {
        $post_id = intval($_POST['post']['id']);
        if( empty($post_id) ) {
            return ;
        }
        $posts_model = M( 'Posts' );
        $article = $posts_model
            ->alias("a")
            ->field('a.*,b.term_id')
            ->join("__TERM_RELATIONSHIPS__ b ON a.id = b.object_id", 'LEFT')
            ->where( "a.id={$post_id}" )->find();
        if( empty($article) ) {
            return ;
        }
        $url = leuu( 'article/index', array( 'id'=>$article['id'], 'cid'=>$article['term_id'] ), true, true );
        die( "edit_post: {$url}" );
//        $res = $this->_update( array( $url ) );
    }

    // 刪除文章
    public function portalAdminpostDelete( $id='' ) {
        // 若是id參數爲空就取get參數
        empty($id) && ($id = I("get.id",0,'intval'));
        if( empty($id) ) {
            return ;
        }
        $posts_model = M( 'Posts' );
        $article = $posts_model
            ->alias("a")
            ->field('a.*,b.term_id')
            ->join("__TERM_RELATIONSHIPS__ b ON a.id = b.object_id", 'LEFT')
            ->where( "a.id={$id}" )->find();
        if( empty($article) ) {
            return ;
        }
        $url = leuu( 'article/index', array( 'id'=>$article['id'], 'cid'=>$article['term_id'] ), true, true );
        die( "delete: {$url}" );
//        $res = $this->_del( array( $url ) );
    }

    // 文章還原
    public function portalAdminpostRestore() {
        $id = I("get.id", 0, 'intval');
        if( empty($id) ) {
            return ;
        }
        $posts_model = M( 'Posts' );
        $article = $posts_model
            ->alias("a")
            ->field('a.*,b.term_id')
            ->join("__TERM_RELATIONSHIPS__ b ON a.id = b.object_id", 'LEFT')
            ->where( "a.id={$id}" )->find();
        if( empty($article) ) {
            return ;
        }
        $url = leuu( 'article/index', array( 'id'=>$article['id'], 'cid'=>$article['term_id'] ), true, true );
        die( "restore: {$url}" );
//        $res = $this->_urls( array( $url ) );
    }

}

二、複製BaiduLinkSubmitBehavior.class.php文件到目錄application/Common/Behavior/BaiduLinkSubmitBehavior.class.php中並修改sitetoken類常量。

三、在application/Common/Conf/tags.php文件中加入:

'action_end' => array(    'Common\Behavior\BaiduLinkSubmitBehavior')

四、關閉index.php中的debug模式:define("APP_DEBUG", false);

開發中(打開debug模式)添加的文章沒推送怎麼辦?

在每一個頁面的HTML代碼中包含如下自動推送JS代碼:

<script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https'){
   bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
  }
  else{
  bp.src = 'http://push.zhanzhang.baidu.com/push.js';
  }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>

安裝自動推送JS代碼的網頁,在頁面被訪問時,頁面URL將當即被推送給百度。

總結與記錄

相關文章
相關標籤/搜索