1

这是我2017年的开篇,也是我在Segmentfault的第一篇文章,写的不好还请多多包涵,我是一位码农,在segmentfault得到自己的一块小田地,喜欢这里的归属感,我愿意每天在这块地里劳作,记录我的学习、工作、生活中的珍贵点滴。

以下信息根据您的兴趣推荐:

王思聪4200万生日趴豪奢曝光,香槟王灌到饱。
台湾康师傅宣布解散,大陆业务营运不受影响。
“五福事件”再次来袭!网友评论:马云,看来你是没被骂够!

每天新闻咋这么多,刷的停不下来都没时间工作了。(旁白君:喂喂,打住,你好像跑偏了!),想想每天网络信息流如此巨大,如果网站不及时把原创好文章推送给搜索引擎,基本就会埋没在信息流中。(旁白君:好像是那么回事!)

使用主动推送功能会达到怎样效果

及时发现:可以缩短百度爬虫发现您站点新链接的时间,使新发布的页面可以在第一时间被百度收录。

保护原创:对于网站的最新原创内容,使用主动推送功能可以快速通知到百度,使内容可以在转发之前被百度发现。

(旁白君:有没有这么厉害哦?)

信不信看官方介绍:百度站长平台推送介绍

ThinkPHP行为扩展

行为(Behavior)是一个比较抽象的概念,类似于AOP编程中的“切面”的概念,给某一个切面绑定相关行为就成了一种类AOP编程的思想。(旁白君:AOP又是什么?),熟悉Java的朋友应该对AOP不陌生:

在运行时,动态地将代码切入到类指定的方法、位置上,这种编程思想就是面向切面的编程。直白的说:在不修改原代码的情况下,给指定方法添加新功能。

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 (控制器结束)标签位。

一切从代码开始

1、在任意地方新建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 ) );
    }

}

2、复制BaiduLinkSubmitBehavior.class.php文件到目录application/Common/Behavior/BaiduLinkSubmitBehavior.class.php中并修改sitetoken类常量。

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

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

4、关闭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将立即被推送给百度。

总结与记录


许剑锋
413 声望23 粉丝

引用和评论

0 条评论