PHP code example of leeprince / laravel-wechat

1. Go to this page and download the library: Download leeprince/laravel-wechat library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

leeprince / laravel-wechat example snippets

index.php
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce     = $_GET["nonce"];
$echostr   = $_GET["echostr"];

$token  = 'leeprinceSubscription';
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);

if ($tmpStr == $signature) {
    // 微信服务器在验证业务服务器地址的有效性时,包含 echostr 参数,之后微信服务器与业务服务器的交互不再包含此参数。
    if (empty($echostr)) {
        /**
         * 开始处理业务
         */
        return true;
    } else {
        // 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容. 此处只能使用 echo,使用 return 失败。
        echo $echostr;
    }
} else {
    return false;
}

/**
 * 引入 composer 组件中的服务提供者
 */
// 自定义服务提供者 - 基于微信公众号开发的 composer 组件
LeePrince\WeChat\WeChatServiceProvider::class,
angular2
Router::any('hello', function() {
   dump('hello world');
});

/**
 * [引导服务:该方法在所有服务提供者被注册以后才会被调用]
 *
 * @Author  leeprince:2020-03-22 19:55
 */
public function boot()
{
    $this->loadRoutes();
}

/**
 * [加载路由]
 *
 * @Author  leeprince:2020-03-23 00:28
 */
private function loadRoutes()
{
    Route::group(['namespace' => 'LeePrince\WeChat\Http\Controllers', 'prefix' => 'wechat'], function() {
        $this->loadRoutesFrom(__DIR__.'/Route/route.php');
    });
}
angular2


namespace LeePrince\WeChat\Http\Controllers;

use Illuminate\Http\Request;

/**
 * [微信公众号 - 订阅号接受微信服务验证、接受微信从订阅号发送过来的信息并自动回复]
 *
 * @Author  leeprince:2020-03-22 20:06
 * @package LeePrince\WeChat\Http\Controllers
 */
class WxSubscriptionController extends Controller
{
    /**
     * [自动回复微信公众号信息]
     *
     * @Author  leeprince:2020-03-24 01:10
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        /**
         * 开始处理业务
         */
        $signature = $request->input("signature");
        $timestamp = $request->input("timestamp");
        $nonce     = $request->input("nonce");
        $echostr   = $request->input("echostr");

        $token  = 'leeprinceSubscription';
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if ($tmpStr == $signature) {
            // 微信服务器在验证业务服务器地址的有效性时,包含 echostr 参数,之后微信服务器与业务服务器的交互不再包含此参数。
            if (empty($echostr)) {
                /**
                 * 开始处理业务
                 */
                
                // 回复信息
                // 接收微信发送的参数
                $postObj =file_get_contents('php://input');
                $postArr = simplexml_load_string($postObj,"SimpleXMLElement",LIBXML_NOCDATA);
                if (empty($postArr)) {
                    return response('XML消息为空!');
                }
                //消息内容
                $content = $postArr->Content;
                //接受者
                $toUserName = $postArr->ToUserName;
                //发送者
                $fromUserName = $postArr->FromUserName;
                //获取时间戳
                $time = time();
                
                //回复消息内容; 补充:想更加只能可以通过接入机器人自动回复。比如图灵机器人:http://www.tuling123.com
                $content = "[PrinceProgramming] - 编程是一门艺术\n欢迎您,您的消息是: $content\n";
                //回复文本消息的格式:把百分号(%)符号替换成一个作为参数进行传递的变量
                $info = sprintf("<xml>
                  <ToUserName><![CDATA[%s]]></ToUserName>
                  <FromUserName><![CDATA[%s]]></FromUserName>
                  <CreateTime>%s</CreateTime>
                  <MsgType><![CDATA[text]]></MsgType>
                  <Content><![CDATA[%s]]></Content>
                </xml>", $fromUserName, $toUserName, $time, $content);
                
                return response($info);
            } else {
                // 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容. 此处只能使用 echo,使用 return 失败。
                echo $echostr;
            }
        } else {
            return response('false');
        }

    }
}


/**
 * [服务提供者为 laravel 提供该组件的所有服务]
 *
 * @Author  leeprince:2020-03-22 19:05
 */

namespace LeePrince\WeChat;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;

class WeChatServiceProvider extends ServiceProvider
{
    // 中间件组
    private $middlewareGroups = [];
    
    // 路由中间件
    private $routeMiddleware = [
        'wechat.subscription.CheckSignture' => \LeePrince\WeChat\Http\Middleware\CheckSignture::class,
    ];
    
    /**
     * [注册服务:register 方法中,你只需要将服务绑定到服务容器中。而不要尝试在 register 方法中注册任何监听器,路由,或者其他任何功能。否则,你可能会意外地使用到尚未加载的服务提供者提供的服务。]
     *
     * @Author  leeprince:2020-03-22 19:56
     */
    public function register()
    {
       
    }
    
    /**
     * [引导服务:该方法在所有服务提供者被注册以后才会被调用]
     *
     * @Author  leeprince:2020-03-22 19:55
     */
    public function boot()
    {
        $this->syncMiddlewareToRouter();
    }
    
    /**
     * 将中间件的当前状态同步到路由器
     *
     * @return void
     */
    private function syncMiddlewareToRouter()
    {
        foreach ($this->middlewareGroups as $key => $middleware) {
            Route::middlewareGroup($key, $middleware);
            // $this->router->middlewareGroup($key, $middleware);
        }
        
        foreach ($this->routeMiddleware as $key => $middleware) {
            Route::aliasMiddleware($key, $middleware);
        }
    }
}


/**
 * [服务提供者为 laravel 提供该组件的所有服务]
 *
 * @Author  leeprince:2020-03-22 19:05
 */

namespace LeePrince\WeChat;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;

class WeChatServiceProvider extends ServiceProvider
{
    /**
     * [注册服务:register 方法中,你只需要将服务绑定到服务容器中。而不要尝试在 register 方法中注册任何监听器,路由,或者其他任何功能。否则,你可能会意外地使用到尚未加载的服务提供者提供的服务。]
     *
     * @Author  leeprince:2020-03-22 19:56
     */
    public function register()
    {
    
    }
    
    /**
     * [引导服务:该方法在所有服务提供者被注册以后才会被调用]
     *
     * @Author  leeprince:2020-03-22 19:55
     */
    public function boot()
    {
        $this->loadViews();
    }
    /**
     * [加载视图]
     *
     * @Author  leeprince:2020-03-24 01:08
     */
    private function loadViews()
    {
        $this->loadViewsFrom(__DIR__."/Resources/views/", 'wechatview');
    }
}

Route::any('welcome',  function() {
    // 注意在 WeChatServerProvider 服务提供者中 loadViewsFrom 方法为视图路径设置的命名空间。
    // 所以此处的写法必须是: 设置的命名空间::视图模版名称(去掉.blade.php)
    return view('wechatview::welcome');
});



/**
 * leeprince/laravel-wechat composer 组件中的配置文件
 *      是执行命令  php artisan vendor:publish --provider="LeePrince\WeChat\WeChatServiceProvider" 生成的配置文件
 */
return [
    'wechat_template' => [
        // 文本模板
        'text'  => '
            <xml>
              <ToUserName><![CDATA[%s]]></ToUserName>
              <FromUserName><![CDATA[%s]]></FromUserName>
              <CreateTime>%s</CreateTime>
              <MsgType><![CDATA[text]]></MsgType>
              <Content><![CDATA[%s]]></Content>
            </xml>',
        // 图片模板
        'image'  => '
            <xml>
                <ToUserName><![CDATA[%s]]></ToUserName>
                <FromUserName><![CDATA[%s]]></FromUserName>
                <CreateTime>%s</CreateTime>
                <MsgType><![CDATA[image]]></MsgType>
                <Image>
                    <MediaId><![CDATA[%s]]></MediaId>
                </Image>
            </xml>',
        // 图文模板
        'news'  =>[
            'TplHead' => '
                  <xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[news]]></MsgType>
                    <ArticleCount>%s</ArticleCount>
                    <Articles>',
            'TplBody' => '
                    <item>
                        <Title><![CDATA[%s]]></Title>
                        <Description><![CDATA[%s]]></Description>
                        <PicUrl><![CDATA[%s]]></PicUrl>
                        <Url><![CDATA[%s]]></Url>
                    </item>',
            'TplFoot' => '
                    </Articles>
                  </xml>'
        ],
    ]
];



/**
 * [服务提供者为 laravel 提供该组件的所有服务]
 *
 * @Author  leeprince:2020-03-22 19:05
 */

namespace LeePrince\WeChat;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;

class WeChatServiceProvider extends ServiceProvider
{
    /**
     * [注册服务:register 方法中,你只需要将服务绑定到服务容器中。而不要尝试在 register 方法中注册任何监听器,路由,或者其他任何功能。否则,你可能会意外地使用到尚未加载的服务提供者提供的服务。]
     *
     * @Author  leeprince:2020-03-22 19:56
     */
    public function register()
    {
        $this->registerConfigFile();
    }
    
    /**
     * [引导服务:该方法在所有服务提供者被注册以后才会被调用]
     *
     * @Author  leeprince:2020-03-22 19:55
     */
    public function boot()
    {

    }
    /**
     * [注册配置文件]
     *
     * @Author  leeprince:2020-03-25 00:43
     */
    private function registerConfigFile()
    {
        // 将给定配置与现有配置合并。
        // 指定的 key = 配置的文件名。即可让配置文件合并到由 $this->publishes([__DIR__ . '/Config' => config_path()], $groups = null); 分配的由文件名组成的同一个组中
        $this->mergeConfigFrom(__DIR__ . "/Config/wechat.php", 'wechat');
    }
}

Route::any('config',  function() {
    dump(config());
    // dump(config('wechat'));
    // dump(config('wechat.wechat_template'));
    // dump(config('wechat.wechat_template.text'));
});


/**
 * [服务提供者为 laravel 提供该组件的所有服务]
 *
 * @Author  leeprince:2020-03-22 19:05
 */

namespace LeePrince\WeChat;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;

class WeChatServiceProvider extends ServiceProvider
{
    /**
     * [注册服务:register 方法中,你只需要将服务绑定到服务容器中。而不要尝试在 register 方法中注册任何监听器,路由,或者其他任何功能。否则,你可能会意外地使用到尚未加载的服务提供者提供的服务。]
     *
     * @Author  leeprince:2020-03-22 19:56
     */
    public function register()
    {
        $this->registerConfigFilePublishing();
    }
    
    /**
     * [引导服务:该方法在所有服务提供者被注册以后才会被调用]
     *
     * @Author  leeprince:2020-03-22 19:55
     */
    public function boot()
    {
    
    }
    /**
     * [执行 vendor:publish 命令发布配置文件到指令目录,即可以发布配置文件到指定目录,达到允许外部修改配置文件信息的目的]
     *      执行:php artisan vendor:publish --provider="LeePrince\WeChat\WeChatServiceProvider"
     *
     * @Author  leeprince:2020-03-25 00:43
     */
    private function registerConfigFilePublishing()
    {
        // 确定应用程序是否正在控制台中运行。
        if ($this->app->runningInConsole()) {
            // 注册要由 publish 命令发布的路径,可以发布配置文件到指定目录
            $this->publishes([__DIR__ . '/Config' => config_path()], null);
        }
    }
}


/**
 * [创建控制器的命令]
 *
 * @Author  leeprince:2020-03-25 02:10
 */

namespace LeePrince\WeChat\Console;

use Illuminate\Routing\Console\ControllerMakeCommand;
use Illuminate\Support\Str;

class MakeWechatComposerControllerCommand extends ControllerMakeCommand
{
     // 控制台命令名称。
    protected $name = 'make:wetchatcomposercontroller';
    
    // 控制台命令的描述
    protected $description = '创建 leeprince/laravel-wechat composer 组件包中的控制器';
    
    private $rootNamespace = 'LeePrince\Wechat';
    
    /**
     * 获取该类的根名称空间。
     *
     * @return string
     */
    protected function rootNamespace()
    {
        return $this->rootNamespace;
    }
    
    /**
     * 获取目标类路径。
     *
     * @param  string  $name
     * @return string
     */
    protected function getPath($name)
    {
        $name = Str::replaceFirst($this->rootNamespace(), '', $name);
        
        return __DIR__.'/../'.str_replace('\\', '/', $name).'.php';
    }
}


/**
 * [服务提供者为 laravel 提供该组件的所有服务]
 *
 * @Author  leeprince:2020-03-22 19:05
 */

namespace LeePrince\WeChat;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;

class WeChatServiceProvider extends ServiceProvider
{
    /**
     * 自定义 Artisan 命令
     *      创建控制器到组件中
     */
    private $commands = [
        Console\MakeWechatComposerControllerCommand::class
    ];
    
    /**
     * [注册服务:register 方法中,你只需要将服务绑定到服务容器中。而不要尝试在 register 方法中注册任何监听器,路由,或者其他任何功能。否则,你可能会意外地使用到尚未加载的服务提供者提供的服务。]
     *
     * @Author  leeprince:2020-03-22 19:56
     */
    public function register()
    {
        $this->registerCommands();
    }
    /**
     * [注册软件包的自定义 Artisan 命令。]
     *
     * @Author  leeprince:2020-03-25 02:07
     */
    private function registerCommands()
    {
        $this->commands($this->commands);
    }
}


/**
* 引入 composer 组件中的服务提供者
*/
// 自定义服务提供者 - 基于微信公众号开发的 composer 组件
LeePrince\WeChat\WeChatServiceProvider::class,