php异步多线程swoole使用实例程序

 更新时间:2016年11月25日 16:19  点击:2018
swoole重新定义PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务了,下面我们为了证实它就来做一个例子测试一下吧。

Swoole 提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询.
swoole以前听过, 拿来做游戏服务器简直是神器…今天稍微的感受了一下,  在 ubuntu 下搭建了环境, 测试了一下

测试代码:

 代码如下 复制代码

<?php
class page extends Controller
{
    function index()
    {
        $data = createModel('UserInfo')->get(12)->get();
        $this->swoole->tpl->assign('data',$data);
        $html = $this->swoole->tpl->fetch('test.html');
        $time = $this->showTime();
        return $html.$time;
    }
}

shell
ab -c 100 -n 1000 -k http://127.0.0.1/index/
 
Requests per second
Time per request (mean)
Time per request (mean, across all concurrent requests)

运行方式
Swoole EventTCP Swoole SelectTCP Swoole BlockTCP Apache/Prefork
单进程
571.70 [#/sec] 174.916 [ms] 1.749 [ms] 659.01 [#/sec]
151.743 [ms]
1.517 [ms]
561.24 [#/sec]
178.178 [ms]
1.782
80.57
1241.083 [ms]
12.411 [ms]
4进程
1153.63 [#/sec]
86.683 [ms]
0.867 [ms]
1010.08 [#/sec]
99.002 [ms]
0.990 [ms]
1094.58 [#/sec]
91.359 [ms]
0.914 [ms]

apache下居然也有这么好的效率, 留个爪子.以后好用

随着 php5 面向对象的完善,现在很多php主流框架都往面向对象发展。Drupal8为了适应新php主题框架的需要,也将用面向对象的方式取代面向过程,在Proudly Found Elsewhere的倡议下,Dupal8包含了很多看起来不像是为了drupal开发的的代码。

其中最大的变化是引入了Symfony框架,这对开发人员来说,会产生两个重大影响

首先,这可能将会大大增加Drupal开发者的数量,比如那些曾经自认为是大师,不屑于面向过程开发的传统"高端程序猿",现在Drupal8,也是面向对像了,也用了新框架,他们已经没有理由拒绝加入drupal开发者的行列

第二,新的框架内核变化,会给现在那些没有多少PHP现代框架开发经验的人许多恐惧,他们会担心自己不能适应这种开发方式的巨大转变,但是没关系,我们都需要重新学习,学习Symfony框架,还有充满希望的Drupal8, 像其他PHP框架一样,它们都是很容易扩展的,我们要给自己信心。

在目前,Drupal 8 还在其发布周期中,目前最新的版本是alpha12,我们会基于这个版本,来展示一些Drupal 7开发者会先遇到的一些基本变化,我们应该先熟悉这些基本变化。

我怎样创建一个模块?

我们第一件事是要确定必须的文件和文件夹结构来告诉Drupal8识别我们的新模块。在Drupal 7 里,我们必须创建至少2个文件(.info 和 .module文件),但是在Drupal 8里,.info文件替换成了.info.yml,文件里的内容数据信息相同,但格式略有差异。

另一个主要变化是,自定义模块和第三方贡献模块文件夹的存放位置现在被放到了根目录下的modules/,这是因为所有核心的代码已经被移动到了它单独的文件夹core/,当然,在根目录下的modules文件夹内,我们依然鼓励你像以往的Drupal 7 一样,可以创建 custom 和contrib 子文件夹来分别存放你的自定义模块和官网下载的第三方模块。

让我们继续,我们现在先来学习创建一个叫demo(非常简单)的模块,并把它放到modules/custom/文件夹下,正如我之前所提到的,我们需要在这个新创建的demo/文件夹里,创建一个 demo.info.yml 文件,并在文件里输入以下代码:

 代码如下 复制代码
name: Drupal 8 Demo module
description: 'Demo module for Drupal 8 alpha12'
type: module
core: 8.x



这些大部分你应该看着很熟悉吧(name, description and core), type 字段也是现在必须有的一项,它的值可以是module,theme,theme_engine分别定义此文件类型是模块,还是主题或者模板引擎,另外要注意的一件重要的细节是,注意yml文件里的空格,正确缩进可以像数组一样组织数据。

你可以查看此文档 (https://www.drupal.org/node/2000204)说里其他可用的key|value , 然后打开一个模块文件夹下的.info.yml文件,尝试改变key|value,这里是官方的变更说明 (https://www.drupal.org/node/1935708)

现在,只要有这一个文件就足够了,你可以进入导航菜单下的Extend(扩展)页,找到Demo模块,并启用它。

正如我之前提到的,现在我不需要再创建一个.module的文件,drupal 8就已经可以识别此模块了,因为在drupal 8里,.module文件已经不再是必须存在的文件。因为现在大部分的业务逻辑代码都转移到了service类,控制器和插件里,我们稍后会看到这一点。

什么是路由?调用hook_menu()会发生什么?它的回调怎么工作?


在drupal 7里,hook_menu()可能是最能实现这些功能需求的钩子,因为它就是被用于设定路径并且把这些路径和回调函数连接起来,它也用来创建菜单链接和其他一些东西

在Drupal 8里,我们不再需要hook_menu()了,因为我们会大量使用Symfony2的组件来处理路由,这涉及定义一个路由配置和在控制器里处理一个回调(Controller类的方法), 让我们来实际看下它是如何工作的,我们来创建一个简单的页面来输出那句程序界的永恒经典:Hello world!

首先,我们需要为我们的模块创建一个路由文件:demo.routing.yml ,这个文件也是放在demo模块根目录下,在这个文件里,我们可以有如下(简单)路由设定:

 代码如下 复制代码

demo.demo:
  path: '/demo'
  defaults:
    _content: 'DrupaldemoControllerDemoController::demo'
    _title: 'Demo'
  requirements:
    _permission: 'access content'




第一行代码是一个新路由的开始,这个路由的名字叫做demo(原作者真蛋疼,你就不能取一个不一样的路由名嘛,非要和模块名一样,你让我的小伙伴误会了怎么办?),第一个是demo是模块名,第二个demo是路由名.

第二行path, 我们指定了这个路由的注册路径。

第三行defaults默认设置,我们设定了两件事:默认的页面标题(_title)和引用一个DemoController类的一个方法(_content)

第四行requirements要求,我们指定了用户需要有什么权限才能查看该页面。

你可以查此文档 (https://www.drupal.org/node/2092643)知道你还可以在这个路由文件里设定哪些选项。

现在,让我们来创建第一个叫做DemoController的控制器,并且它包含了一个方法叫做:demo(),用于当用户访问该页面时调用此方法。

在模块目录里,创建一个src的文件夹和一个Controller的文件夹,这就是我们存放controller类的地方,好了,进入Controller文件夹,创建文件:DemoController.php。

该控制器的位置,正如我们将看到的一样,把其他类放入src文件夹里是采用PSR-4标准的一部分,在之前,我们有一个更深层更大的文件夹结构(PSR-0标准),但现在有一个过渡阶段,这两种标准的文件夹结构路径都会起作用,所以你如果看到代码类仍然被放在lib/文件夹下,不用觉得奇怪,那是PSR-0标准。

在DemoController.php文件里,我们可以声明我们的类了:

 代码如下 复制代码

<?php
/**
 * @file
 * Contains DrupaldemoControllerDemoController.
 */

namespace DrupaldemoController;

/**
 * DemoController.
 */
class DemoController {
  /**
   * Generates an example page.
   */
  public function demo() {
    return array(
      '#markup' => t('Hello World!'),
    );
  }     
}


这是我们为了在一个页面上显示"Hello World!"的一个结构最简单的实例,在顶部,我们指定了类的命名空间,在下面,我们声明了我们的类

在DemoController类里,我们只需要demo()方法,用来返回一个像以往的drupal 7里一样的渲染数组,没有大量的东西,现在我们要做的就是清空缓存,并在浏览器里输入地址:http://example.com/demo ,然后我们就应该可以看到一个输出有Hello World!的页面!

怎么创建菜单链接?

在Drupal 7里,为了让菜单链接显示在网站上,我们可以在实施hook_menu()时,添加已经注册过的路径,但在Drupal8里,这个不再需要用hook来处理,我们可以像配置一样使用一个yml文件来声明菜单链接

让我们来看看,该怎样创建一个菜单链接来显示在Structure(结构)管理菜单下,首先,我们在我们的模块根目录下创建一个demo.menu_links.yml 文件,在这个文件中,我们将设定菜单链接和在现有网站菜单上的位置,为了实现我们所要做的,我们需要在文件里输入以下代码:

 代码如下 复制代码

demo.demo:
title: Demo Link
description: 'This is a demo link'
parent: system.admin_structure
route_name: demo.demo



这又是一个基于缩进的yml结构文件,

第一行我们定义了模块的菜单链接的机器名(就像之前定义路由一样),接下来,我们设定了链接的标题,描述,父菜单路径(作为子菜单放在该父菜单下),以及该菜单关联的路由名。

父菜单选项的值是父菜单路径(通它的所属模块附加),你想找个这个父菜单链接,你需要查找一些类似的*.menu_links.yml文件,因为这里的值是system.admin_structure,所以我就可以知道,它肯定是由核心的System模块设定的,所以你就可以判断这个父菜单链接存在于system.menu_links.yml文件里。

route_name是我们想要为这个菜单关联的路由名(这们之前创建的),当你清空缓存后,然后输入浏览器地址:http://example.com/admin/structure你应该可以看到一个新的菜单标题和描述,并且此链接是链接到demo/path的,怎么样,很不错吧?
结论

在这篇文章中,我们开始讨论Drupal 8 的模块开发,在这个阶段(alpha12发布),正是开始学习怎样使用新的API接口来开发贡献模块,为此,我会大家一起退出传统框架的思维,用全新的思维一起探索学习Drupal 8的变化。

首先,我们了解了一些基础知识,如何启动一个Drupal8模块(文件和文件夹结构等),所有这些与Drupal 7的不同之处,我们还看到了如何设定路由和一个控制器类的方法来调用一个路由地址,最后,我们已经看到了如何创建一个使用我们所定义路由的菜单链接。

在接下来的教程中,我们将继续构建完善这个模块,并期待发现在Drupal8中其他一些很酷的东西,我们将看到我们如何创建区块和如何配合使用表单和配置管理系统,下期见。

使用php编程的同学都希望自己写的php代码最高效率执行,特别是初学者还没掌握的时候,现在我从网上收集了50个提高php编程执行效率的方法,希望对大家有用

1、用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说echo是语言结构,不是真正的函数,故把函数加上了双引号)。

2、如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍。

3、$row[’id’] 的速度是$row[id]的7倍。

4、echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接,比如echo $str1,$str2。

5、在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替。

6、注销那些不用的变量尤其是大数组,以便释放内存。

7、尽量避免使用__get,__set,__autoload。

8、require_once()代价昂贵。

9、include文件时尽量使用绝对路径,因为它避免了PHP去include_path里查找文件的速度,解析操作系统路径所需的时间会更少。

10、如果你想知道脚本开始执行(译注:即服务器端收到客户端请求)的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()。

11、函数代替正则表达式完成相同功能。

12、str_replace函数比preg_replace函数快,但strtr函数的效率是str_replace函数的四倍。

13、如果一个字符串替换函数,可接受数组或字符作为参数,并且参数长度不太长,那么可以考虑额外写一段替换代码,使得每次传递参数是一个字符,而不是只写一行代码接受数组作为查询和替换的参数。

14、使用选择分支语句(译注:即switch case)好于使用多个if,else if语句。

15、用@屏蔽错误消息的做法非常低效,极其低效。

16、打开apache的mod_deflate模块,可以提高网页的浏览速度。

17、数据库连接当使用完毕时应关掉,不要用长连接。

18、错误消息代价昂贵。

19、在方法中递增局部变量,速度是最快的。几乎与在函数中调用局部变量的速度相当。

20、递增一个全局变量要比递增一个局部变量慢2倍。

21、递增一个对象属性(如:$this->prop++)要比递增一个局部变量慢3倍。

22、递增一个未预定义的局部变量要比递增一个预定义的局部变量慢9至10倍。

23、仅定义一个局部变量而没在函数中调用它,同样会减慢速度(其程度相当于递增一个局部变量)。PHP大概会检查看是否存在全局变量。

24、方法调用看来与类中定义的方法的数量无关,因为我(在测试方法之前和之后都)添加了10个方法,但性能上没有变化。

25、派生类中的方法运行起来要快于在基类中定义的同样的方法。

26、调用带有一个参数的空函数,其花费的时间相当于执行7至8次的局部变量递增操作。类似的方法调用所花费的时间接近于15次的局部变量递增操作。

27、Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面,少用脚本。

28、除非脚本可以缓存,否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25%至100%的性能,以免除编译开销。

29、尽量做缓存,可使用memcached。memcached是一款高性能的内存对象缓存系统,可用来加速动态Web应用程序,减轻数据库负载。对运算码 (OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。

30、当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步骤,如字母小写化(译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset() 技巧加速执行你的代码。(举例如下)if (strlen($foo) < 5) { echo “Foo is too short”$$ }(与下面的技巧做比较)if (!isset($foo{5})) { echo “Foo is too short”$$ }调用isset()恰巧比strlen()快,因为与后者不同的是,isset()作为一种语言结构,意味着它的执行不需要函数查找和字母小写化。也就是说,实际上在检验字符串长度的顶层代码中你没有花太多开销。

31、当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java代码并指望它们能立即变快,没用的。++$i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变量,这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意,因为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服务提供商(ISPs)和服务器。

32、并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。

33、并非要用类实现所有的数据结构,数组也很有用。

34、不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?

35、当你需要时,你总能把代码分解成方法。

36、尽量采用大量的PHP内置函数。

37、如果在代码中存在大量耗时的函数,你可以考虑用C扩展的方式实现它们。

38、评估检验(profile)你的代码。检验器会告诉你,代码的哪些部分消耗了多少时间。Xdebug调试器包含了检验程序,评估检验总体上可以显示出代码的瓶颈。

39、mod_zip可作为Apache模块,用来即时压缩你的数据,并可让数据传输量降低80%。

40、在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题;

41、尽量的少进行文件操作,虽然PHP的文件操作效率也不低的;

42、优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作(在update上,我被恶批过);

43、尽可能的使用PHP内部函数(但是我却为了找个PHP里面不存在的函数,浪费了本可以写出一个自定义函数的时间,经验问题啊!);

44、循环内部不要声明变量,尤其是大变量:对象(这好像不只是PHP里面要注意的问题吧?);

45、多维数组尽量不要循环嵌套赋值;

46、在可以用PHP内部字符串操作函数的情况下,不要用正则表达式;

47、foreach效率更高,尽量用foreach代替while和for循环;

48、用单引号替代双引号引用字符串;

49、“用i+=1代替i=i+1。符合c/c++的习惯,效率还高”;

50、对global变量,应该用完就unset()掉;

Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在 Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。

Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在 Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。

XML:(Extensible Markup Language)扩展型可标记语言。面向短期的临时数据处理、面向万维网络,是Soap的基础。

Soap: (Simple Object Access Protocol)简单对象存取协议。是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的 调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。

WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。

UDDI (Universal Description, Discovery, and Integration) 是一个主要针对Web服务供应商和使用者的新项目。在用户能够调用Web服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服 务端来编制软件,UDDI是一种根据描述文档来引导系统查找相应服务的机制。UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览 以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

微信公众号点击菜单即可打开并登录微站实现步骤比较复杂了,但很多微站在己用上了,所以本文章就为各位整理一下吧,希望可以帮助到大家哦。

现在大部分微站都通过用户的微信openid来实现自动登录。在我之前的开发中,用户通过点击一个菜单,公众号返回一个图文,用户点击这个图文才可以自动登录微站。但是如果你拥有高级接口,就可以实现点击菜单,打开网页就能获取这个openid,实现自动登录。

这里已经提到,必须要拥有高级接口的权限(服务号、企业号),开启了开发者模式。

1.设置回调地址 ↑

在微信公众平台后台“开发者中心”中找到“高级接口”下的“OAuth2.0网页授权”,后面有一个“修改”,点击之后就会弹出填写回调地址的对话框。具体如何授权,请点击这里学习。只有获得高级接口权限后,才能出现这个地方的“修改”。

注意,这里填写的是域名,不是带http://的网址,而且解释中很清楚,“授权回调域名配置规范为全域名”,也就是说带www和不带是不同的两个域名。因此我这里要填写如下图中的域名。

微信公众号点击菜单即可打开并登录微站实现步骤

2. 创建菜单 ↑

创建菜单可以通过你的微站后台创建,如果没有开启开发者模式,也可以通过微信公众平台后台创建。

菜单使用点击打开链接的模式,也就是view模式。如果你是使用开发者模式,通过向微信提交如下代码,即可创建公众号菜单(开发者文档):

 代码如下 复制代码
 {
     "button":[
     { 
          "type":"view",
          "name":"登录微站",
          "url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid={在微信公众平台后台获取这个APPID}&redirect_uri={你填写的回调域名下的地址}&response_type=code&scope=snsapi_base&state=1#wechat_redirect"
      }]
 }

代码1 要提交的菜单代码,下面要用到

APPID的获取位置就是上面你填写回调地址的那个“开发者中心”。下面我们用PHP来实现一下菜单提交:

 代码如下 复制代码
<?php
function curl_info($appid,$secret) {
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  // curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $tmpInfo = curl_exec($ch);
  if (curl_errno($ch)) { 
    echo 'Errno'.curl_error($ch);
  }
  curl_close($ch);
  $arr= json_decode($tmpInfo,true);
  return $arr;
}
function curl_menu($ACCESS_TOKEN,$data) {
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$ACCESS_TOKEN);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $tmpInfo = curl_exec($ch);
  if (curl_errno($ch)) {
    echo 'Errno'.curl_error($ch);
  }
  curl_close($ch);
  $arr= json_decode($tmpInfo,true);
  return $arr;
}
function creat_menu() {
  $ACCESS_LIST= curl_info(APP_ID,APP_SCR);//获取到的凭证,你需要自己define APP_ID和APP_SCR(应用密钥),这个也是在微信公众平台后台开发者中心找
  if($ACCESS_LIST['access_token']!='') {
    $access_token = $ACCESS_LIST['access_token'];//获取到ACCESS_TOKEN
    $data = '把上面代码1拷贝黏贴在这里';
    $msg = curl_menu($access_token,preg_replace("#u([0-9a-f]+)#ie", "iconv('UCS-2', 'UTF-8', pack('H4', '1'))", $data));
    if($msg['errmsg']=='ok') {
      die('创建自定义菜单成功!');
    }
    else {
      die('创建自定义菜单失败!');
    }
  }
  else {
    die('创建失败,微信AppId或微信AppSecret填写错误');
  }
}
create_menu();
?>

代码2 用PHP来创建微信公众号菜单

代码2其实有点冗余了,核心部分用红色标出来了。就这样,你的微信公众号中应该很快就可以看到创建了一个“登录微站”的菜单。点击这个菜单就可以实现登录微站了。

如果你不需要PHP,可以直接在微信公众平台后台的菜单自定义中写链接就可以了。

微信公众号点击菜单即可打开并登录微站实现步骤

在上图中的这个地方,选择打开链接的方式创建菜单。OK,接下来把上面那个链接放进去:

https://open.weixin.qq.com/connect/oauth2/authorize?appid={在微信公众平台后台获取这个APPID}&redirect_uri={你填写的回调域名下的地址}&response_type=code&scope=snsapi_base&state=1#wechat_redirect
创建菜单就可以了。

当然,你也有可能只需要在你自己的微信管理后台加入这个链接就可以了。

3.在回调页获取openid ↑

细心的你可能已经发现了,上面的链接地址中含有参数scope=snsapi_base,而非scope=snsapi_userinfo,因为使用前者不需要用户点击一个授权按钮,直接跳转到回调页面,而后者需要点击授权按钮,不过点击授权按钮有好处,一是可以在没有关注公众号的情况下也可以授权,二是授权后可以获得用户的一些信息,如昵称、性别、所在地。但是我们是为了利用openid进行登录,所以直接选择前者就可以了。

点击菜单之后,经过微信authorize的处理,会跳转到你提交的回调地址(这里需要提醒,回调地址最好不要带参数,例如xxx/?callback=from_weixin,因为微信跳转到你的回调地址也要带参数,而这个参数就你需要的)。微信跳转到如下URL:

回调地址/?code=CODE&state=1
上面代码可以通过$_GET['code']获得一个CODE值,利用这个CODE值和appid,可以获得openid和access_token。

下面再用PHP来实现以下:

 代码如下 复制代码

if($_GET['code']) {
  $code = $_GET['code'];
  $data = get_by_curl('https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSRC&code='.$code.'&grant_type=authorization_code');
  $data = json_decode($data);
  $openid = $data->openid;
  $access_token = $data->access_token;
}

function get_by_curl($url,$post = false){
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if($post){
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
    }
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

这样可以就可以获得openid和access_token,利用这些值,我们还可以利用微信公众平台的获取用户基本信息api接口获取用户基本信息。

[!--infotagslink--]

相关文章

  • 图解PHP使用Zend Guard 6.0加密方法教程

    有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
  • ps怎么使用HSL面板

    ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。 &#8195;...2017-07-06
  • Plesk控制面板新手使用手册总结

    许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
  • 使用insertAfter()方法在现有元素后添加一个新元素

    复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31
  • jQuery 1.9使用$.support替代$.browser的使用方法

    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31
  • C#注释的一些使用方法浅谈

    C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
  • 使用percona-toolkit操作MySQL的实用命令小结

    1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24
  • 使用GruntJS构建Web程序之构建篇

    大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
  • 如何使用php脚本给html中引用的js和css路径打上版本号

    在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24
  • MySQL日志分析软件mysqlsla的安装和使用教程

    一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
  • 安装和使用percona-toolkit来辅助操作MySQL的基本教程

    一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24
  • 使用jquery修改表单的提交地址基本思路

    基本思路: 通过使用jquery选择器得到对应表单的jquery对象,然后使用attr方法修改对应的action 示例程序一: 默认情况下,该表单会提交到page_one.html 点击button之后,表单的提交地址就会修改为page_two.html 复制...2014-06-07
  • php语言中使用json的技巧及json的实现代码详解

    目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。我写过一篇《数据类型和JSON格式》,探讨它的设计思想。今天,我想总结一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识...2015-10-30
  • PHP实现无限级分类(不使用递归)

    无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
  • php类的使用实例教程

    php类的使用实例教程 <?php /** * Class program for yinghua05-2 * designer :songsong */ class Template { var $tpl_vars; var $tpl_path; var $_deb...2016-11-25
  • 双冒号 ::在PHP中的使用情况

    前几天在百度知道里面看到有人问PHP中双冒号::的用法,当时给他的回答比较简洁因为手机打字不大方便!今天突然想起来,所以在这里总结一下我遇到的双冒号::在PHP中使用的情况!双冒号操作符即作用域限定操作符Scope Resoluti...2015-11-08
  • 深入分析C#中的异步和多线程

    这篇文章主要介绍了C#中异步和多线程的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2021-01-16
  • 浅析Promise的介绍及基本用法

    Promise是异步编程的一种解决方案,在ES6中Promise被列为了正式规范,统一了用法,原生提供了Promise对象。接下来通过本文给大家介绍Promise的介绍及基本用法,感兴趣的朋友一起看看吧...2021-10-21
  • PHP mysql与mysqli事务使用说明 分享

    mysqli封装了诸如事务等一些高级操作,同时封装了DB操作过程中的很多可用的方法。应用比较多的地方是 mysqli的事务。...2013-10-02
  • C#多线程与异步的区别详解

    多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别...2020-06-25