您正在查看: 标签 thinkphp 下的文章

使用thinkphp5开发的小案例

本教程由四哥许坤原创。转载请注明出处。四哥许坤唯一官方博客:http://blog.kunx.org


最近有很多同学在问我thinkphp5的问题,顺手录制了一个小案例,不能面面俱到。

建议大家先看手册,看一下目录,知道都是有些什么,然后用到的时候知道去哪里查。

当然如果能够通读几遍更好。


我从国家统计局抓取了70万条区划数据,发现有乱码,就用thinkphp5写了一个区划名称校对的项目。里面用到的thinkphp5的知识并不是太多,欢迎大家交流。



地址:http://location.kunx.org/

欢迎大家帮我校对数据,非常感谢。


视频放在B站,因为没有广告

http://www.bilibili.com/video/av7668348/


1482511273222929.jpg

1482511275263095.jpg

1482511273736174.jpg



提供一个分页样式thinkphp3可用

提供一个分页样式,在thinkphp3中可用,但是由于thinkphp3的分页类封装的没有可扩展性,所以必须修改源码才可以使用

最终效果如下:

thinkphp_page.png


为了不修改框架源文件,我在application文件夹下的common文件夹中添加了一个helper文件夹,在里面创建了一个新的分页类文件,此文件和框架的分页类基本一致,只不过在分页工具条外面添加了一个page1类选择器


<?php
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 四哥许坤 <kunx-edu@qq.com> 
// +----------------------------------------------------------------------
namespace Common\Helper;

class Page{
    public $firstRow; // 起始行数
    public $listRows; // 列表每页显示行数
    public $parameter; // 分页跳转时要带的参数
    public $totalRows; // 总行数
    public $totalPages; // 分页总页面数
    public $rollPage   = 11;// 分页栏每页显示的页数
    public $lastSuffix = true; // 最后一页是否显示总页数

    private $p       = 'p'; //分页参数名
    private $url     = ''; //当前链接URL
    private $nowPage = 1;

	// 分页显示定制
    private $config  = array(
        'header' => '<span class="rows">共 %TOTAL_ROW% 条记录</span>',
        'prev'   => '<<',
        'next'   => '>>',
        'first'  => '1...',
        'last'   => '...%TOTAL_PAGE%',
        'theme'  => '%FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END%',
    );

    /**
     * 架构函数
     * @param array $totalRows  总的记录数
     * @param array $listRows  每页显示记录数
     * @param array $parameter  分页跳转的参数
     */
    public function __construct($totalRows, $listRows=20, $parameter = array()) {
        C('VAR_PAGE') && $this->p = C('VAR_PAGE'); //设置分页参数名称
        /* 基础设置 */
        $this->totalRows  = $totalRows; //设置总记录数
        $this->listRows   = $listRows;  //设置每页显示行数
        $this->parameter  = empty($parameter) ? $_GET : $parameter;
        $this->nowPage    = empty($_GET[$this->p]) ? 1 : intval($_GET[$this->p]);
        $this->nowPage    = $this->nowPage>0 ? $this->nowPage : 1;
        $this->firstRow   = $this->listRows * ($this->nowPage - 1);
    }

    /**
     * 定制分页链接设置
     * @param string $name  设置名称
     * @param string $value 设置值
     */
    public function setConfig($name,$value) {
        if(isset($this->config[$name])) {
            $this->config[$name] = $value;
        }
    }

    /**
     * 生成链接URL
     * @param  integer $page 页码
     * @return string
     */
    private function url($page){
        return str_replace(urlencode('[PAGE]'), $page, $this->url);
    }

    /**
     * 组装分页链接
     * @return string
     */
    public function show() {
        if(0 == $this->totalRows) return '';

        /* 生成URL */
        $this->parameter[$this->p] = '[PAGE]';
        $this->url = U(ACTION_NAME, $this->parameter);
        /* 计算分页信息 */
        $this->totalPages = ceil($this->totalRows / $this->listRows); //总页数
        if(!empty($this->totalPages) && $this->nowPage > $this->totalPages) {
            $this->nowPage = $this->totalPages;
        }

        /* 计算分页临时变量 */
        $now_cool_page      = $this->rollPage/2;
		$now_cool_page_ceil = ceil($now_cool_page);
		$this->lastSuffix && $this->config['last'] = $this->totalPages;

        //上一页
        $up_row  = $this->nowPage - 1;
        $up_page = $up_row > 0 ? '<a class="prev" href="' . $this->url($up_row) . '">' . $this->config['prev'] . '</a>' : '';

        //下一页
        $down_row  = $this->nowPage + 1;
        $down_page = ($down_row <= $this->totalPages) ? '<a class="next" href="' . $this->url($down_row) . '">' . $this->config['next'] . '</a>' : '';

        //第一页
        $the_first = '';
        if($this->totalPages > $this->rollPage && ($this->nowPage - $now_cool_page) >= 1){
            $the_first = '<a class="first" href="' . $this->url(1) . '">' . $this->config['first'] . '</a>';
        }

        //最后一页
        $the_end = '';
        if($this->totalPages > $this->rollPage && ($this->nowPage + $now_cool_page) < $this->totalPages){
            $the_end = '<a class="end" href="' . $this->url($this->totalPages) . '">' . $this->config['last'] . '</a>';
        }

        //数字连接
        $link_page = "";
        for($i = 1; $i <= $this->rollPage; $i++){
			if(($this->nowPage - $now_cool_page) <= 0 ){
				$page = $i;
			}elseif(($this->nowPage + $now_cool_page - 1) >= $this->totalPages){
				$page = $this->totalPages - $this->rollPage + $i;
			}else{
				$page = $this->nowPage - $now_cool_page_ceil + $i;
			}
            if($page > 0 && $page != $this->nowPage){

                if($page <= $this->totalPages){
                    $link_page .= '<a class="num" href="' . $this->url($page) . '">' . $page . '</a>';
                }else{
                    break;
                }
            }else{
                if($page > 0 && $this->totalPages != 1){
                    $link_page .= '<span class="current">' . $page . '</span>';
                }
            }
        }

        //替换分页内容
        $page_str = str_replace(
            array('%HEADER%', '%NOW_PAGE%', '%UP_PAGE%', '%DOWN_PAGE%', '%FIRST%', '%LINK_PAGE%', '%END%', '%TOTAL_ROW%', '%TOTAL_PAGE%'),
            array($this->config['header'], $this->nowPage, $up_page, $down_page, $the_first, $link_page, $the_end, $this->totalRows, $this->totalPages),
            $this->config['theme']);
        return "<div class='page1'>{$page_str}</div>";
    }
}


附,样式文件:

/*thinkphp 分页样式*/
div.page1 {
    margin-top: 20px;
    margin-right: 10px;
    float: right;
    color: #666;
}

div.page1 span.current , div.page1 a{
    border: 1px solid #dcdcdc;
    display: block;
    float: left;
    font-size: 12px;
    margin-right: 5px;
    padding: 3px 10px;
    text-decoration: none;
    border-radius: 3px;
}
div.page1 span.current{
    background: #ff5c5c none repeat scroll 0 0 !important;
    border-color: #ff5c5c;
    color: #ffffff !important;
    display: block;
    float: left;
    font-size: 12px;
    cursor: pointer;
}
div.page1 a.prev,div.page1 a.next{
    padding: 3px 4px;
}

div.page1 span.rows{
    border: 1px solid #dcdcdc;
    display: inline-block;
    /*float: left;*/
    font-size: 12px;
    margin-right: 5px;
    padding: 3px 10px;
    text-decoration: none;
    border-radius: 3px;
}


基于thinkphp5的微信支付sdk


微信支付的sdk和文档都写得让人非常头疼,代码格式不讲究,代码注释不讲究,甚至还有错误,实在是让人崩溃。

为了方便使用四哥基于thinkphp5做了一个扩展,欢迎大家使用。


当然此类sdk有很多,功能也更加完善,比如easywechat和wechat-php-sdk大家可以自行搜索。强烈推荐使用这些sdk而不是原生sdk。


主要修改的文件有

文件WxPay.Api.php

/**
 * 
 * 支付结果通用通知
 * @param function $callback
 * 直接回调函数使用方法: notify(you_function);
 * 回调类成员函数方法:notify(array($this, you_function));
 * $callback  原型为:function function_name($data){}
 */
 public static function notify($callback, &$msg) {
    //获取通知的数据
    //$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
    /**
     * kunx <kunx-edu@qq.com>
     * php5.3之后默认禁止了HTTP_RAW_POST_DATA这种方式
     * 在php7的版本中,直接就不再支持。
     */
    $xml = file_get_contents('php://input');
    //如果返回成功则验证签名
    try {
        $result = WxPayResults::Init($xml);
    } catch (WxPayException $e) {
        $msg = $e->errorMessage();
        return false;
    }

    return call_user_func($callback, $result);
}


WxPay.Notify

/**
 * 
 * 回调入口
 * @param bool $needSign  是否需要签名输出
 */
final public function Handle($needSign = true) {
    $msg    = "OK";
    //当返回false的时候,表示notify中调用NotifyCallBack回调失败获取签名校验失败,此时直接回复失败
    /**
     * kunx <kunx-edu@qq.com>
     * 2016-11-23
     * 此处原来写的是WxpayApi,导致自己写的自动加载机制实效,当然可以在自动加载机制中不区分大小写解决。
     */
    $result = WxPayApi::notify(array($this, 'NotifyCallBack'), $msg);
    if ($result == false) {
        $this->SetReturn_code("FAIL");
        $this->SetReturn_msg($msg);
        $this->ReplyNotify(false);
        return;
    } else {
        //该分支在成功回调到NotifyCallBack方法,处理完成之后流程
        $this->SetReturn_code("SUCCESS");
        $this->SetReturn_msg("OK");
    }
    $this->ReplyNotify($needSign);
}


基于thinkphp5的微信扫码支付sdk

修复微信支付中安全问题及bug:

  • 修复sdk中的拼写错误

  • 修复php5.3之后默认禁用always_populate_raw_post_data(php7中直接去除了此特性)导致的xml获取失败的问题

  • 简单的自动加载机制

  • 账号信息放在配置文件中,以便修改

  • 更加简单的文件结构,只有两个文件夹,一个是core放置了类文件,cert文件夹放置证书

  • 完善的demo文件 > application/index/controller/Index.php

配置

请在配置文件添加配置信息,结构如下:

'wxpay'=>[
    'appid'=>'your appid',
    'mchid'=>'your mchid',
    'key'=>'your key',
    'appsecret'=>'your appsecret',
],


日志放置在项目目录下的logs文件中,请确保文件夹可写

代码已托管至github,地址为:https://github.com/kunx-edu/wxpay-tp5



thinkphp5模型的坑

老博客数据还在,但是上传附件目录结构变化了,于是想写个脚本修改数据,既然有thinkphp5,就用它吧,毕竟要支持一下国产框架……


代码非常简单,由于是一次性使用,所以在应用中有多个数据库操作,为了方便,就通过模型的属性指定数据库配置:

代码如下:

<?php


namespace app\blog\model;

/**
 * 文章表
 *
 * @author kunx-edu <kunx-edu@qq.com>
 */
class Post extends \think\Model {
    protected $table = 'wp_posts';

    // 设置当前模型的数据库连接
    protected $connection = [
        'type'     => 'mysql',
        'hostname' => '127.0.0.1',
        'database' => 'kunx_blog',
        'username' => 'hansome_man',
        'password' => 'cpt6tptp6cptdtptp',
        'charset'  => 'utf8',
        'prefix'   => 'wp_',
        'debug'    => false,
    ];

}

控制器代码如下:

<?php

namespace app\blog\controller;

/**
 * Description of Repair
 *
 * @author qingf
 */
class Repair extends \think\Controller{
    
    public function index() {
        $cond = [
            'post_title'=>['<>',''],
            'post_content'=>['<>',''],
        ];
        /**
         * @var \app\blog\model\Post
         */
        $model = new \app\blog\model\Post;
        
        $articles = $model->field('id,post_content')->where($cond)->select();
        foreach($articles as &$item){
            $item['post_content'] = str_replace('/wp-content/uploads/', '/uploads/', $item['post_content']);
        }
        unset($item);
        $model->saveAll($articles);
    }
}

不可谓不简单,但是,

table_column.png


WTF,我直接崩溃了,调试发现:

table_error.png

好吧,您老,不带自己过滤字段的么?


那我过滤总行了吧

把控制器最后一行改为

$model->allowField(['id,post_content'])->saveAll($articles);

还是同样的错误,WTF!

好,那兄弟我在循环的时候执行保存

foreach($articles as &$item){
            $item['post_content'] = str_replace('/wp-content/uploads/', '/uploads/', $item['post_content']);
            $item->save();
        }

where_error.png


你到底跟主流框架有多大仇!非要这样任性!

原因是:

将对象所有数据获取,而不是合法的数据,比如各种私有属性也用了

如果从对象的data属性中获取和设置,就没有这个问题了,但是不知道官方什么时候修复。



最后代码改成:

<?php

namespace app\blog\controller;

class Repair extends \think\Controller{
    
    public function index() {
        $cond = [
            'post_title'=>['<>',''],
            'post_content'=>['<>',''],
        ];
        /**
         * @var \app\blog\model\Post
         */
        $model = new \app\blog\model\Post;
        
        $articles = $model->field('id,post_content')->where($cond)->select();
        foreach($articles as &$item){
            $item['post_content'] = str_replace('/wp-content/uploads/', '/uploads/', $item['post_content']);
            $item = $item->toArray();
        }
        unset($item);
        $model->saveAll($articles);
    }
}

已经无力吐槽!

thinkphp5快速入门视频

四哥原创教程。

01.png

ThinkPHP5发布了,想给爱好者提供一个入门教程。

时间所限,只能仓促而就,不足之处,请多海涵,谬误之处,在所难免,欢迎指正。


如果大家有需要,精力充沛的时候,可以录制更多教程。


感谢大家!


分享链接:https://pan.baidu.com/s/1pLKXwpl