博客

  • GitHub OAuth 第三方登录示例教程

    作者: 阮一峰

    日期: 2019年4月21日

    这组 OAuth 系列教程,第一篇介绍了基本概念,第二篇介绍了获取令牌的四种方式,今天演示一个实例,如何通过 OAuth 获取 API 数据。

    很多网站登录时,允许使用第三方网站的身份,这称为"第三方登录"。

    下面就以 GitHub 为例,写一个最简单的应用,演示第三方登录。

    一、第三方登录的原理

    所谓第三方登录,实质就是 OAuth 授权。用户想要登录 A 网站,A 网站让用户提供第三方网站的数据,证明自己的身份。获取第三方网站的身份数据,就需要 OAuth 授权。

    举例来说,A 网站允许 GitHub 登录,背后就是下面的流程。

    1. A 网站让用户跳转到 GitHub。
    2. GitHub 要求用户登录,然后询问"A 网站要求获得 xx 权限,你是否同意?"
    3. 用户同意,GitHub 就会重定向回 A 网站,同时发回一个授权码。
    4. A 网站使用授权码,向 GitHub 请求令牌。
    5. GitHub 返回令牌.
    6. A 网站使用令牌,向 GitHub 请求用户数据。

    下面就是这个流程的代码实现。

    二、应用登记

    一个应用要求 OAuth 授权,必须先到对方网站登记,让对方知道是谁在请求。

    所以,你要先去 GitHub 登记一下。当然,我已经登记过了,你使用我的登记信息也可以,但为了完整走一遍流程,还是建议大家自己登记。这是免费的。

    访问这个网址,填写登记表。

    应用的名称随便填,主页 URL 填写http://localhost:8080,跳转网址填写 http://localhost:8080/oauth/redirect

    提交表单以后,GitHub 应该会返回客户端 ID(client ID)和客户端密钥(client secret),这就是应用的身份识别码。

    三、示例仓库

    我写了一个代码仓库,请将它克隆到本地。

    
    $ git clone git@github.com:ruanyf/node-oauth-demo.git
    $ cd node-oauth-demo
    

    两个配置项要改一下,写入上一步的身份识别码。

    然后,安装依赖。

    
    $ npm install
    

    启动服务。

    
    $ node index.js
    

    浏览器访问http://localhost:8080,就可以看到这个示例了。

    四、浏览器跳转 GitHub

    示例的首页很简单,就是一个链接,让用户跳转到 GitHub。

    跳转的 URL 如下。

    
    https://github.com/login/oauth/authorize?
      client_id=7e015d8ce32370079895&
      redirect_uri=http://localhost:8080/oauth/redirect
    

    这个 URL 指向 GitHub 的 OAuth 授权网址,带有两个参数:client_id告诉 GitHub 谁在请求,redirect_uri是稍后跳转回来的网址。

    用户点击到了 GitHub,GitHub 会要求用户登录,确保是本人在操作。

    五、授权码

    登录后,GitHub 询问用户,该应用正在请求数据,你是否同意授权。

    用户同意授权, GitHub 就会跳转到redirect_uri指定的跳转网址,并且带上授权码,跳转回来的 URL 就是下面的样子。

    
    http://localhost:8080/oauth/redirect?
      code=859310e7cecc9196f4af
    

    后端收到这个请求以后,就拿到了授权码(code参数)。

    六、后端实现

    示例的后端采用 Koa 框架编写,具体语法请看教程

    这里的关键是针对/oauth/redirect的请求,编写一个路由,完成 OAuth 认证。

    
    const oauth = async ctx => {
      // ...
    };
    
    app.use(route.get('/oauth/redirect', oauth));
    

    上面代码中,oauth函数就是路由的处理函数。下面的代码都写在这个函数里面。

    路由函数的第一件事,是从 URL 取出授权码。

    
    const requestToken = ctx.request.query.code;
    

    七、令牌

    后端使用这个授权码,向 GitHub 请求令牌。

    
    const tokenResponse = await axios({
      method: 'post',
      url: 'https://github.com/login/oauth/access_token?' +
        `client_id=${clientID}&` +
        `client_secret=${clientSecret}&` +
        `code=${requestToken}`,
      headers: {
        accept: 'application/json'
      }
    });
    

    上面代码中,GitHub 的令牌接口https://github.com/login/oauth/access_token需要提供三个参数。

    • client_id:客户端的 ID
    • client_secret:客户端的密钥
    • code:授权码

    作为回应,GitHub 会返回一段 JSON 数据,里面包含了令牌accessToken

    
    const accessToken = tokenResponse.data.access_token;
    

    八、API 数据

    有了令牌以后,就可以向 API 请求数据了。

    
    const result = await axios({
      method: 'get',
      url: `https://api.github.com/user`,
      headers: {
        accept: 'application/json',
        Authorization: `token ${accessToken}`
      }
    });
    

    上面代码中,GitHub API 的地址是https://api.github.com/user,请求的时候必须在 HTTP 头信息里面带上令牌Authorization: token 361507da

    然后,就可以拿到用户数据,得到用户的身份。

    
    const name = result.data.name;
    ctx.response.redirect(`/welcome.html?name=${name}`);
    

    (完)

    文档信息

    • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证
    • 发表日期: 2019年4月21日
  • OAuth 2.0 的四种方式

    作者: 阮一峰

    日期: 2019年4月 9日

     

    上一篇文章介绍了 OAuth 2.0 是一种授权机制,主要用来颁发令牌(token)。本文接着介绍颁发令牌的实务操作。

    下面我假定,你已经理解了 OAuth 2.0 的含义和设计思想,否则请先阅读这个系列的上一篇文章

    RFC 6749

    OAuth 2.0 的标准是 RFC 6749 文件。该文件先解释了 OAuth 是什么。

    OAuth 引入了一个授权层,用来分离两种不同的角色:客户端和资源所有者。……资源所有者同意以后,资源服务器可以向客户端颁发令牌。客户端通过令牌,去请求数据。

    这段话的意思就是,OAuth 的核心就是向第三方应用颁发令牌。然后,RFC 6749 接着写道:

    (由于互联网有多种场景,)本标准定义了获得令牌的四种授权方式(authorization grant )。

    也就是说,OAuth 2.0 规定了四种获得令牌的流程。你可以选择最适合自己的那一种,向第三方应用颁发令牌。下面就是这四种授权方式。

    • 授权码(authorization-code)
    • 隐藏式(implicit)
    • 密码式(password):
    • 客户端凭证(client credentials)

    注意,不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。

    第一种授权方式:授权码

    授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。

    这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

    第一步,A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。下面就是 A 网站跳转 B 网站的一个示意链接。

    
    https://b.com/oauth/authorize?
      response_type=code&
      client_id=CLIENT_ID&
      redirect_uri=CALLBACK_URL&
      scope=read
    

    上面 URL 中,response_type参数表示要求返回授权码(code),client_id参数让 B 知道是谁在请求,redirect_uri参数是 B 接受或拒绝请求后的跳转网址,scope参数表示要求的授权范围(这里是只读)。

    第二步,用户跳转后,B 网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 B 网站就会跳回redirect_uri参数指定的网址。跳转时,会传回一个授权码,就像下面这样。

    
    https://a.com/callback?code=AUTHORIZATION_CODE
    

    上面 URL 中,code参数就是授权码。

    第三步,A 网站拿到授权码以后,就可以在后端,向 B 网站请求令牌。

    
    https://b.com/oauth/token?
     client_id=CLIENT_ID&
     client_secret=CLIENT_SECRET&
     grant_type=authorization_code&
     code=AUTHORIZATION_CODE&
     redirect_uri=CALLBACK_URL
    

    上面 URL 中,client_id参数和client_secret参数用来让 B 确认 A 的身份(client_secret参数是保密的,因此只能在后端发请求),grant_type参数的值是AUTHORIZATION_CODE,表示采用的授权方式是授权码,code参数是上一步拿到的授权码,redirect_uri参数是令牌颁发后的回调网址。

    第四步,B 网站收到请求以后,就会颁发令牌。具体做法是向redirect_uri指定的网址,发送一段 JSON 数据。

    
    {    
      "access_token":"ACCESS_TOKEN",
      "token_type":"bearer",
      "expires_in":2592000,
      "refresh_token":"REFRESH_TOKEN",
      "scope":"read",
      "uid":100101,
      "info":{...}
    }
    

    上面 JSON 数据中,access_token字段就是令牌,A 网站在后端拿到了。

    第二种方式:隐藏式

    有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。

    第一步,A 网站提供一个链接,要求用户跳转到 B 网站,授权用户数据给 A 网站使用。

    
    https://b.com/oauth/authorize?
      response_type=token&
      client_id=CLIENT_ID&
      redirect_uri=CALLBACK_URL&
      scope=read
    

    上面 URL 中,response_type参数为token,表示要求直接返回令牌。

    第二步,用户跳转到 B 网站,登录后同意给予 A 网站授权。这时,B 网站就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。

    
    https://a.com/callback#token=ACCESS_TOKEN
    

    上面 URL 中,token参数就是令牌,A 网站因此直接在前端拿到令牌。

    注意,令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。

    这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。

    第三种方式:密码式

    如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。

    第一步,A 网站要求用户提供 B 网站的用户名和密码。拿到以后,A 就直接向 B 请求令牌。

    
    https://oauth.b.com/token?
      grant_type=password&
      username=USERNAME&
      password=PASSWORD&
      client_id=CLIENT_ID
    

    上面 URL 中,grant_type参数是授权方式,这里的password表示"密码式",usernamepassword是 B 的用户名和密码。

    第二步,B 网站验证身份通过后,直接给出令牌。注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,A 因此拿到令牌。

    这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。

    第四种方式:凭证式

    最后一种方式是凭证式(client credentials),适用于没有前端的命令行应用,即在命令行下请求令牌。

    第一步,A 应用在命令行向 B 发出请求。

    
    https://oauth.b.com/token?
      grant_type=client_credentials&
      client_id=CLIENT_ID&
      client_secret=CLIENT_SECRET
    

    上面 URL 中,grant_type参数等于client_credentials表示采用凭证式,client_idclient_secret用来让 B 确认 A 的身份。

    第二步,B 网站验证通过以后,直接返回令牌。

    这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

    令牌的使用

    A 网站拿到令牌以后,就可以向 B 网站的 API 请求数据了。

    此时,每个发到 API 的请求,都必须带有令牌。具体做法是在请求的头信息,加上一个Authorization字段,令牌就放在这个字段里面。

    
    curl -H "Authorization: Bearer ACCESS_TOKEN" \
    "https://api.b.com"
    

    上面命令中,ACCESS_TOKEN就是拿到的令牌。

    更新令牌

    令牌的有效期到了,如果让用户重新走一遍上面的流程,再申请一个新的令牌,很可能体验不好,而且也没有必要。OAuth 2.0 允许用户自动更新令牌。

    具体方法是,B 网站颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。

    
    https://b.com/oauth/token?
      grant_type=refresh_token&
      client_id=CLIENT_ID&
      client_secret=CLIENT_SECRET&
      refresh_token=REFRESH_TOKEN
    

    上面 URL 中,grant_type参数为refresh_token表示要求更新令牌,client_id参数和client_secret参数用于确认身份,refresh_token参数就是用于更新令牌的令牌。

    B 网站验证通过以后,就会颁发新的令牌。

    写到这里,颁发令牌的四种方式就介绍完了。下一篇文章会编写一个真实的 Demo,演示如何通过 OAuth 2.0 向 GitHub 的 API 申请令牌,然后再用令牌获取数据。

    (正文完)

  • OAuth 2.0 的一个简单解释

    作者: 阮一峰

    日期: 2019年4月 4日

     

    OAuth 2.0 是目前最流行的授权机制,用来授权第三方应用,获取用户数据。

    这个标准比较抽象,使用了很多术语,初学者不容易理解。其实说起来并不复杂,下面我就通过一个简单的类比,帮助大家轻松理解,OAuth 2.0 到底是什么。

    一、快递员问题

    我住在一个大型的居民小区。

    小区有门禁系统。

    进入的时候需要输入密码。

    我经常网购和外卖,每天都有快递员来送货。我必须找到一个办法,让快递员通过门禁系统,进入小区。

    如果我把自己的密码,告诉快递员,他就拥有了与我同样的权限,这样好像不太合适。万一我想取消他进入小区的权力,也很麻烦,我自己的密码也得跟着改了,还得通知其他的快递员。

    有没有一种办法,让快递员能够自由进入小区,又不必知道小区居民的密码,而且他的唯一权限就是送货,其他需要密码的场合,他都没有权限?

    二、授权机制的设计

    于是,我设计了一套授权机制。

    第一步,门禁系统的密码输入器下面,增加一个按钮,叫做"获取授权"。快递员需要首先按这个按钮,去申请授权。

    第二步,他按下按钮以后,屋主(也就是我)的手机就会跳出对话框:有人正在要求授权。系统还会显示该快递员的姓名、工号和所属的快递公司。

    我确认请求属实,就点击按钮,告诉门禁系统,我同意给予他进入小区的授权。

    第三步,门禁系统得到我的确认以后,向快递员显示一个进入小区的令牌(access token)。令牌就是类似密码的一串数字,只在短期内(比如七天)有效。

    第四步,快递员向门禁系统输入令牌,进入小区。

    有人可能会问,为什么不是远程为快递员开门,而要为他单独生成一个令牌?这是因为快递员可能每天都会来送货,第二天他还可以复用这个令牌。另外,有的小区有多重门禁,快递员可以使用同一个令牌通过它们。

    三、互联网场景

    我们把上面的例子搬到互联网,就是 OAuth 的设计了。

    首先,居民小区就是储存用户数据的网络服务。比如,微信储存了我的好友信息,获取这些信息,就必须经过微信的"门禁系统"。

    其次,快递员(或者说快递公司)就是第三方应用,想要穿过门禁系统,进入小区。

    最后,我就是用户本人,同意授权第三方应用进入小区,获取我的数据。

    简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。

    四、令牌与密码

    令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。

    (1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。

    (2)令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。

    (3)令牌有权限范围(scope),比如只能进小区的二号门。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。

    上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。

    注意,只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。 这也是为什么令牌的有效期,一般都设置得很短的原因。

    OAuth 2.0 对于如何颁发令牌的细节,规定得非常详细。具体来说,一共分成四种授权类型(authorization grant),即四种颁发令牌的方式,适用于不同的互联网场景。下一篇文章,我就来介绍这四种类型,并给出代码实例。

    (完)

    文档信息

    • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证
    • 发表日期: 2019年4月 4日

  • 五分钟带你了解啥是JWT

    1. JSON Web Token是什么

    JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

    2. 什么时候你应该用JSON Web Token

    下列场景中使用JSON Web Token是很有用的:

    • Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
    • Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWT可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。

    3. JSON Web Token的结构是什么样的

    JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:

    • Header
    • Payload
    • Signature

    因此,一个典型的JWT看起来是这个样子的:

    xxxxx.yyyyy.zzzzz

    接下来,具体看一下每一部分:

    • Header header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。
       

    例如:

    {
        'alg': "HS256",
        'typ': "JWT"
    }

     

    然后,用Base64对这个JSON编码就得到JWT的第一部分

    • Payload JWT的第二部分是payload,它包含声明(要求)。声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型: registered, public 和 private。

       

      • Registered claims : 这里有一组预定义的声明,它们不是强制的,但是推荐。比如:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。
      • Public claims : 可以随意定义。
      • Private claims : 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。 下面是一个例子:
    {
        "sub": '1234567890',
        "name": 'john',
        "admin":true
    }

     

    对payload进行Base64编码就得到JWT的第二部分

    注意,不要在JWT的payload或header中放置敏感信息,除非它们是加密的。

    • Signature

    为了得到签名部分,你必须有编码过的header、编码过的payload、一个秘钥,签名算法是header中指定的那个,然对它们签名即可。

    例如:

    HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

    签名是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。

    看一张官网的图就明白了:


     

    4. JSON Web Tokens是如何工作的

    在认证的时候,当用户用他们的凭证成功登录以后,一个JSON Web Token将会被返回。此后,token就是用户凭证了,你必须非常小心以防止出现安全问题。一般而言,你保存令牌的时候不应该超过你所需要它的时间。

    无论何时用户想要访问受保护的路由或者资源的时候,用户代理(通常是浏览器)都应该带上JWT,典型的,通常放在Authorization header中,用Bearer schema。

    header应该看起来是这样的:

    Authorization: Bearer

    服务器上的受保护的路由将会检查Authorization header中的JWT是否有效,如果有效,则用户可以访问受保护的资源。如果JWT包含足够多的必需的数据,那么就可以减少对某些操作的数据库查询的需要,尽管可能并不总是如此。

    如果token是在授权头(Authorization header)中发送的,那么跨源资源共享(CORS)将不会成为问题,因为它不使用cookie。

    5. 基于Token的身份认证 与 基于服务器的身份认证

    5.1 基于服务器的身份认证

    在讨论基于Token的身份认证是如何工作的以及它的好处之前,我们先来看一下以前我们是怎么做的:

    HTTP协议是无状态的,也就是说,如果我们已经认证了一个用户,那么他下一次请求的时候,服务器不知道我是谁,我们必须再次认证

    传统的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器以此检查用户是否认证过。

    这种基于服务器的身份认证方式存在一些问题:

    • Sessions : 每次用户认证通过以后,服务器需要创建一条记录保存用户信息,通常是在内存中,随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大。
    • Scalability : 由于Session是在内存中的,这就带来一些扩展性的问题。
    • CORS : 当我们想要扩展我们的应用,让我们的数据被多个移动设备使用时,我们必须考虑跨资源共享问题。当使用AJAX调用从另一个域名下获取资源时,我们可能会遇到禁止请求的问题。
    • CSRF : 用户很容易受到CSRF攻击。

    5.2. JWT与Session的差异 相同点是,它们都是存储用户信息;然而,Session是在服务器端的,而JWT是在客户端的。

    Session方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。

    而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。

    Session的状态是存储在服务器端,客户端只有session id;而Token的状态是存储在客户端。

     


     

    5.3. 基于Token的身份认证是如何工作的 基于Token的身份认证是无状态的,服务器或者Session中不会存储任何用户信息。

    没有会话信息意味着应用程序可以根据需要扩展和添加更多的机器,而不必担心用户登录的位置。

    虽然这一实现可能会有所不同,但其主要流程如下:

    -用户携带用户名和密码请求访问 -服务器校验用户凭据 -应用提供一个token给客户端 -客户端存储token,并且在随后的每一次请求中都带着它 -服务器校验token并返回数据

    注意:

    -每一次请求都需要token -Token应该放在请求header中 -我们还需要将服务器设置为接受来自所有域的请求,用Access-Control-Allow-Origin: *

     


     

    5.4. 用Token的好处 – 无状态和可扩展性:Tokens存储在客户端。完全无状态,可扩展。我们的负载均衡器可以将用户传递到任意服务器,因为在任何地方都没有状态或会话信息。 – 安全:Token不是Cookie。(The token, not a cookie.)每次请求的时候Token都会被发送。而且,由于没有Cookie被发送,还有助于防止CSRF攻击。即使在你的实现中将token存储到客户端的Cookie中,这个Cookie也只是一种存储机制,而非身份认证机制。没有基于会话的信息可以操作,因为我们没有会话!

    还有一点,token在一段时间以后会过期,这个时候用户需要重新登录。这有助于我们保持安全。还有一个概念叫token撤销,它允许我们根据相同的授权许可使特定的token甚至一组token无效。

    5.5. JWT与OAuth的区别 -OAuth2是一种授权框架 ,JWT是一种认证协议 -无论使用哪种方式切记用HTTPS来保证数据的安全性 -OAuth2用在使用第三方账号登录的情况(比如使用weibo, qq, github登录某个app),而JWT是用在前后端分离, 需要简单的对后台API进行保护时使用。

     

    文章来源:https://zhuanlan.zhihu.com/p/86937325

  • 范式速记

    第N范式总是满足第N-1范式。

    范式化设计的优点:一般能解决写入的性能问题,原因:1. 范式化设计不存在重复数据,因此修改时写入更少。 2. 范式化的表比较小,因此操作起来更快。

    范式化设计的缺点:真正投入使用时一般查询至少需要join一次,稍复杂一点需要join三到四张表,因此范式化设计会让查询代价变高昂

    正确姿势是根据业务混合范式化和反范式化到设计中,做一定的折中。

    第一范式(1NF)

    列拆无可拆

    不符合范式:
    员工号 信息
    1029 汤米 28岁
    符合范式:
    员工号 姓名 年龄
    1029 汤米 28

    第二范式(2NF)

    抽出关系表

    不符合范式:
    员工号 姓名 年龄 绩效
    1029 汤米 28 A
    符合范式:
    员工号 姓名 年龄
    1029 汤米 28
    员工号 绩效
    1029 A

    第三范式(3NF)

    关系不能存在传递

    不符合范式:
    员工号 姓名 年龄
    1029 汤米 28
    员工号 绩效 奖励
    1029 A 一级
    奖励 年终奖(月) 期权(%)
    一级 6 5

    注:表二存在传递关系。奖励和绩效有直接关系,绩效和员工号有直接关系,但奖励和员工号并非直接关系而是传递关系。应该拆成两张关系表。

    符合范式:
    员工号 姓名 年龄
    1029 汤米 28
    员工号 绩效
    1029 A
    绩效 奖励
    A 一级
    奖励 年终奖(月) 期权(%)
    一级 6 5

     

  • UML建模常用的符号速记

    平常软件设计开发过程中,或多或少都会都会用到UML建模,类图,时序图,活动图等都是在设计一个功能模块的时候明晰开发步骤的重要手段。但是各种图的符号多而复杂,需要一些小技巧来记住它们,准确的表达我们的设计意图。

     

      UML:统一建模语言(Unified Modeling Language).用于说明、可视化、构建和编写一个正在开发的面向对象的、软件密集系统的制品的开放方法。

    结构式图形:强调的是系统的建模

    行为式图形:强调系统模型中触发的事件

    交互式图形:属于行为式图形的子集合,强调系统模型中资料流程。

     

    箭头方向?

    是有知道对方信息的时候才能指向对方,例如,继承关系,子类一定是知道父类的,但是父类不知道子类,所以箭头方向是从子类指向父类的。 

    实线 or 虚线?

    实线  —继承   is a 关系、   

                 关联(关系稳定),表示一个类对象和另一个类对象有关联

     

    虚线  —实现  

                   依赖(临时用一下,若即若离,虚无缥缈,若有若无)

                   表示一种使用关系,一个类需要借助另一个类来实现功能,一般是一个类使用另一个类作为参数使用,或作为返回值。

    空心菱形 or 实心菱形?

    空心菱形:整体和局部的关系,两者有独立的生命周期,是has a的关系,弱关系

                聚合:代表有相同特征的物体聚在一起形成的集合

     

    组合:不同的结构组合在一起形成一个整体,有相同的生命周期,contains-a 的关系,强关系

     

    组合关系中常见的数字表达以及其含义:

    0..1:0或1个实例

    0..* : 0或多个实例

    1..1: 一个实例

    1: 只能有一个实例

    1..* : 至少有一个实例

    作者:池西西
    链接:https://www.jianshu.com/p/5459a582e8f3
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • UML_速记口决

    三十几,三叙事

    零食族,林空聚

    实监官,虚监意

    解释及用法如下:

    三十几:

    三角形实线表示继承

    三叙事

    三角形虚线表示实现接口

    零食族

    菱形实心 表示 组合,箭头指向组合的组成体,组成体中的所有成员变量及方法都应在菱形体中再次作为成员变量使用

    林空聚

    菱形空心 表示 聚合,箭头指向聚合的组成体,组成体中的部分成员变量及方法应在菱形体中再次作为成员变量使用

    实监官

    实线箭头表示关联,箭头指向关联体,关联体都作为实体的成员变量

    虚监意

    虚线箭头表示依赖,箭头指向依赖体所有依赖体作为自己的成员变量,从而在实体中的某特定的方法中调用作为了实体的一个方法体。

    eg 虚监意

    动物Animal(实体) 依赖于 氧气oxygen (依赖体1) 和 水water(依赖体2)
    oxygen和 water共同作为实体的方法的参数,完成新陈代谢 Metabolism

    class Animl {

    public Metabolism(Oxygen oxygen, Water water)  {
    
    }
    
    • 1
    • 2
    • 3

    }

  • 设计模式——速记口诀

    最近在学习设计模式的时候,感觉23种设计模式的名字好难记啊,晦涩难懂啊。不过IT界好心人大有人在啊,下面是转载的文章,一个小口诀就帮助我们记牢23种设计模式。真棒!

    其实我们应该高兴更应该反省,高兴的是不需要自己造轮子,反省的是为什么我们也遇到了同样的问题(名字不好记),但是我们没有去解决呢?或者说没有想办法去解决呢?对待问题的态度值得深思啊!

    设计模式常常被提起,不记住它们的名字怎能行?因此,我编写了这个顺口溜,希望您看了之后也能记得快、记得牢。 

    5 + 7 = 11;5个创建型,7个结构型,11个行为型


    1、创建型速记口诀

     

    抽工单建原

    • Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
    • Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
    • Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory
      Method使一个类的实例化延迟到了子类。
    • Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。
    • Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。


    2、结构型速记口诀

     

    桥代理组装适配器,享元回家装饰外观。

     

    解释:有个姓代理组装适配器,他儿子享元拿回家装饰外观去啦

     

    • Composite,组合模式:将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。
    • Facade,外观模式:为子系统中的一组接口提供一致的界面,facade提供了一高层接口,这个接口使得子系统更容易使用。
    • Proxy,代理模式:为其他对象提供一种代理以控制对这个对象的访问
    • Adapter,适配器模式:将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。
    • Decrator,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。
    • Bridge,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。
    • Flyweight,享元模式


    3、行为型速记口诀

     

    访问者写好策略备忘录,观察模板迭代的状态,命令中介解释责任链。

     

    解释:这句话讲的就是看房子的经过。

    看房子的人就是访问者,看房前要写看房策略备忘录,不能马马虎虎地去看房子。

    去看房子的时候,要仔细观察楼板(模板)层叠(迭代)的状态

    看完房子,命令中介解释清楚产权的责任链

    • Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。
    • Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。
    • Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。
    • Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。
    • State,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。
    • Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。
    • Chain of Responsibility,职责链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系
    • Mediator,中介者模式:用一个中介对象封装一些列的对象交互。
    • Visitor,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。
    • Interpreter,解释器模式:给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
    • Memento,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

     

    大家都知道23中设计模式,其中又可以分成三类,创建型模式,结构型模式,行为型模式。但是总是在实际应用中忘记了,当具体看到一些代码的时候也想不起来具体对应的是哪种设计模式,对经常重构的代码人员来说是一个瑕疵。

    这里我教你三句话巧记23中设计模式,觉得编的好的话点个赞吧 。

    1,创建型模式有五种:工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模式—口诀:原来的建设工人单独抽奖

    解释:原(原型模式)来的建(建造者模式)设工(工厂方法模式)人单(单例模式)独抽(抽象方法模式)奖。

    2,结构型模式有其中:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式—口诀:

    带上适当的装备组合可以让外国侨胞享受(游戏)

    解释:带(代理模式)上适(适配器模式)当的装(装饰模式)备组(组合模式)合可以让外(外观模式)国侨(桥接模式)胞享(享元模式)受(游戏)

    3,行为型模式有十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式—口诀:多次命令和责备中,车模见状慌忙解开(衣服)

    解释:多次(迭:多次的意思,迭代模式)命(命令模式)令和责(责任链模式)备(备忘录模式)中(中介者模式),车(策略模式)

    模(模板方法模式)见(观察着模式)状(状态模式)慌(访问者模式)解(解释器模式)开(衣服)。

    所以只要三句话,当你的脑海中经常有这三句话的时候,23中设计模式就过目不忘了,接下来的就是去实践了吧。

  • 随机生成中文名

    接口参数

    参数名字 类型 是否必须 默认值 其他 说明
    simple 整型 可选     0复姓,1单姓
    len 整型 可选     名字长度

    返回结果

    返回字段 类型 说明
    code 整型 操作码,0表示成功
    info 数组  
    info.name 字符串 名称
    msg 字符串 提示信息

    /**
         * 随机生成中文名
         * @desc 用于随机生成中文名
         * @return int code 操作码,0表示成功
         * @return array info 
         * @return string info.name 名称
         * @return string msg 提示信息
         */
        public function randName()
        {
            $simple=$this->simple;
            $len=$this->len;
            
            $surName = [
                    "赵","钱","孙","李","周","吴","郑","王","冯","陈","楮","卫","蒋","沈","韩","杨",
                    "朱","秦","尤","许","何","吕","施","张","孔","曹","严","华","金","魏","陶","姜",
                    "戚","谢","邹","喻","柏","水","窦","章","云","苏","潘","葛","奚","范","彭","郎",
                    "鲁","韦","昌","马","苗","凤","花","方","俞","任","袁","柳","酆","鲍","史","唐",
                    "费","廉","岑","薛","雷","贺","倪","汤","滕","殷","罗","毕","郝","邬","安","常",
                    "乐","于","时","傅","皮","卞","齐","康","伍","余","元","卜","顾","孟","平","黄",
                    "和","穆","萧","尹","姚","邵","湛","汪","祁","毛","禹","狄","米","贝","明","臧",
                    "计","伏","成","戴","谈","宋","茅","庞","熊","纪","舒","屈","项","祝","董","梁",
                    "杜","阮","蓝","闽","席","季","麻","强","贾","路","娄","危","江","童","颜","郭",
                    "梅","盛","林","刁","锺","徐","丘","骆","高","夏","蔡","田","樊","胡","凌","霍",
                    "虞","万","支","柯","昝","管","卢","莫","经","房","裘","缪","干","解","应","宗",
                    "丁","宣","贲","邓","郁","单","杭","洪","包","诸","左","石","崔","吉","钮","龚",
                    "程","嵇","邢","滑","裴","陆","荣","翁","荀","羊","於","惠","甄","麹","家","封",
                    "芮","羿","储","靳","汲","邴","糜","松","井","段","富","巫","乌","焦","巴","弓",
                    "牧","隗","山","谷","车","侯","宓","蓬","全","郗","班","仰","秋","仲","伊","宫",
                    "宁","仇","栾","暴","甘","斜","厉","戎","祖","武","符","刘","景","詹","束","龙",
                    "叶","幸","司","韶","郜","黎","蓟","薄","印","宿","白","怀","蒲","邰","从","鄂",
                    "索","咸","籍","赖","卓","蔺","屠","蒙","池","乔","阴","郁","胥","能","苍","双",
                    "闻","莘","党","翟","谭","贡","劳","逄","姬","申","扶","堵","冉","宰","郦","雍",
                    "郤","璩","桑","桂","濮","牛","寿","通","边","扈","燕","冀","郏","浦","尚","农",
                    "温","别","庄","晏","柴","瞿","阎","充","慕","连","茹","习","宦","艾","鱼","容",
                    "向","古","易","慎","戈","廖","庾","终","暨","居","衡","步","都","耿","满","弘",
                    "匡","国","文","寇","广","禄","阙","东","欧","殳","沃","利","蔚","越","夔","隆",
                    "师","巩","厍","聂","晁","勾","敖","融","冷","訾","辛","阚","那","简","饶","空",
                    "曾","毋","沙","乜","养","鞠","须","丰","巢","关","蒯","相","查","后","荆","红",
                    "游","竺","权","逑","盖","益","桓","公","晋","楚","阎","法","汝","鄢","涂","钦",
                    "岳","帅","缑","亢","况","后","有","琴","商","牟","佘","佴","伯","赏","墨","哈",
                    "谯","笪","年","爱","阳","佟"];
            
            $doubleSurName= ["万俟","司马","上官","欧阳","夏侯","诸葛","闻人","东方",
                    "赫连","皇甫","尉迟","公羊","澹台","公冶","宗政","濮阳","淳于","单于","太叔","申屠",
                    "公孙","仲孙","轩辕","令狐","锺离","宇文","长孙","慕容","鲜于","闾丘","司徒","司空",
                    "丌官","司寇","仉","督","子车","颛孙","端木","巫马","公西","漆雕","乐正","壤驷","公良",
                    "拓拔","夹谷","宰父","谷梁","段干","百里","东郭","南门","呼延","归海","羊舌","微生",
                    "梁丘","左丘","东门","西门","南宫"];
            
            $word = ["一","乙","二","十","丁","厂","七","卜","人","入","八","九","几","儿","了","力","乃","刀","又",
                    "三","于","干","亏","士","工","土","才","寸","下","大","丈","与","万","上","小","口","巾","山",
                    "千","乞","川","亿","个","勺","久","凡","及","夕","丸","么","广","亡","门","义","之","尸","弓",
                    "己","已","子","卫","也","女","飞","刃","习","叉","马","乡","丰","王","井","开","夫","天","无",
                    "元","专","云","扎","艺","木","五","支","厅","不","太","犬","区","历","尤","友","匹","车","巨",
                    "牙","屯","比","互","切","瓦","止","少","日","中","冈","贝","内","水","见","午","牛","手","毛",
                    "气","升","长","仁","什","片","仆","化","仇","币","仍","仅","斤","爪","反","介","父","从","今",
                    "凶","分","乏","公","仓","月","氏","勿","欠","风","丹","匀","乌","凤","勾","文","六","方","火",
                    "为","斗","忆","订","计","户","认","心","尺","引","丑","巴","孔","队","办","以","允","予","劝",
                    "双","书","幻","玉","刊","示","末","未","击","打","巧","正","扑","扒","功","扔","去","甘","世",
                    "古","节","本","术","可","丙","左","厉","右","石","布","龙","平","灭","轧","东","卡","北","占",
                    "业","旧","帅","归","且","旦","目","叶","甲","申","叮","电","号","田","由","史","只","央","兄",
                    "叼","叫","另","叨","叹","四","生","失","禾","丘","付","仗","代","仙","们","仪","白","仔","他",
                    "斥","瓜","乎","丛","令","用","甩","印","乐","句","匆","册","犯","外","处","冬","鸟","务","包",
                    "饥","主","市","立","闪","兰","半","汁","汇","头","汉","宁","穴","它","讨","写","让","礼","训",
                    "必","议","讯","记","永","司","尼","民","出","辽","奶","奴","加","召","皮","边","发","孕","圣",
                    "对","台","矛","纠","母","幼","丝","式","刑","动","扛","寺","吉","扣","考","托","老","执","巩",
                    "圾","扩","扫","地","扬","场","耳","共","芒","亚","芝","朽","朴","机","权","过","臣","再","协",
                    "西","压","厌","在","有","百","存","而","页","匠","夸","夺","灰","达","列","死","成","夹","轨",
                    "邪","划","迈","毕","至","此","贞","师","尘","尖","劣","光","当","早","吐","吓","虫","曲","团",
                    "同","吊","吃","因","吸","吗","屿","帆","岁","回","岂","刚","则","肉","网","年","朱","先","丢",
                    "舌","竹","迁","乔","伟","传","乒","乓","休","伍","伏","优","伐","延","件","任","伤","价","份",
                    "华","仰","仿","伙","伪","自","血","向","似","后","行","舟","全","会","杀","合","兆","企","众",
                    "爷","伞","创","肌","朵","杂","危","旬","旨","负","各","名","多","争","色","壮","冲","冰","庄",
                    "庆","亦","刘","齐","交","次","衣","产","决","充","妄","闭","问","闯","羊","并","关","米","灯",
                    "州","汗","污","江","池","汤","忙","兴","宇","守","宅","字","安","讲","军","许","论","农","讽",
                    "设","访","寻","那","迅","尽","导","异","孙","阵","阳","收","阶","阴","防","奸","如","妇","好",
                    "她","妈","戏","羽","观","欢","买","红","纤","级","约","纪","驰","巡","寿","弄","麦","形","进",
                    "戒","吞","远","违","运","扶","抚","坛","技","坏","扰","拒","找","批","扯","址","走","抄","坝",
                    "贡","攻","赤","折","抓","扮","抢","孝","均","抛","投","坟","抗","坑","坊","抖","护","壳","志",
                    "扭","块","声","把","报","却","劫","芽","花","芹","芬","苍","芳","严","芦","劳","克","苏","杆",
                    "杠","杜","材","村","杏","极","李","杨","求","更","束","豆","两","丽","医","辰","励","否","还",
                    "歼","来","连","步","坚","旱","盯","呈","时","吴","助","县","里","呆","园","旷","围","呀","吨",
                    "足","邮","男","困","吵","串","员","听","吩","吹","呜","吧","吼","别","岗","帐","财","针","钉",
                    "告","我","乱","利","秃","秀","私","每","兵","估","体","何","但","伸","作","伯","伶","佣","低",
                    "你","住","位","伴","身","皂","佛","近","彻","役","返","余","希","坐","谷","妥","含","邻","岔",
                    "肝","肚","肠","龟","免","狂","犹","角","删","条","卵","岛","迎","饭","饮","系","言","冻","状",
                    "亩","况","床","库","疗","应","冷","这","序","辛","弃","冶","忘","闲","间","闷","判","灶","灿",
                    "弟","汪","沙","汽","沃","泛","沟","没","沈","沉","怀","忧","快","完","宋","宏","牢","究","穷",
                    "灾","良","证","启","评","补","初","社","识","诉","诊","词","译","君","灵","即","层","尿","尾",
                    "迟","局","改","张","忌","际","陆","阿","陈","阻","附","妙","妖","妨","努","忍","劲","鸡","驱",
                    "纯","纱","纳","纲","驳","纵","纷","纸","纹","纺","驴","纽","奉","玩","环","武","青","责","现",
                    "表","规","抹","拢","拔","拣","担","坦","押","抽","拐","拖","拍","者","顶","拆","拥","抵","拘",
                    "势","抱","垃","拉","拦","拌","幸","招","坡","披","拨","择","抬","其","取","苦","若","茂","苹",
                    "苗","英","范","直","茄","茎","茅","林","枝","杯","柜","析","板","松","枪","构","杰","述","枕",
                    "丧","或","画","卧","事","刺","枣","雨","卖","矿","码","厕","奔","奇","奋","态","欧","垄","妻",
                    "轰","顷","转","斩","轮","软","到","非","叔","肯","齿","些","虎","虏","肾","贤","尚","旺","具",
                    "果","味","昆","国","昌","畅","明","易","昂","典","固","忠","咐","呼","鸣","咏","呢","岸","岩",
                    "帖","罗","帜","岭","凯","败","贩","购","图","钓","制","知","垂","牧","物","乖","刮","秆","和",
                    "季","委","佳","侍","供","使","例","版","侄","侦","侧","凭","侨","佩","货","依","的","迫","质",
                    "欣","征","往","爬","彼","径","所","舍","金","命","斧","爸","采","受","乳","贪","念","贫","肤",
                    "肺","肢","肿","胀","朋","股","肥","服","胁","周","昏","鱼","兔","狐","忽","狗","备","饰","饱",
                    "饲","变","京","享","店","夜","庙","府","底","剂","郊","废","净","盲","放","刻","育","闸","闹",
                    "郑","券","卷","单","炒","炊","炕","炎","炉","沫","浅","法","泄","河","沾","泪","油","泊","沿",
                    "泡","注","泻","泳","泥","沸","波","泼","泽","治","怖","性","怕","怜","怪","学","宝","宗","定",
                    "宜","审","宙","官","空","帘","实","试","郎","诗","肩","房","诚","衬","衫","视","话","诞","询",
                    "该","详","建","肃","录","隶","居","届","刷","屈","弦","承","孟","孤","陕","降","限","妹","姑",
                    "姐","姓","始","驾","参","艰","线","练","组","细","驶","织","终","驻","驼","绍","经","贯","奏",
                    "春","帮","珍","玻","毒","型","挂","封","持","项","垮","挎","城","挠","政","赴","赵","挡","挺",
                    "括","拴","拾","挑","指","垫","挣","挤","拼","挖","按","挥","挪","某","甚","革","荐","巷","带",
                    "草","茧","茶","荒","茫","荡","荣","故","胡","南","药","标","枯","柄","栋","相","查","柏","柳",
                    "柱","柿","栏","树","要","咸","威","歪","研","砖","厘","厚","砌","砍","面","耐","耍","牵","残",
                    "殃","轻","鸦","皆","背","战","点","临","览","竖","省","削","尝","是","盼","眨","哄","显","哑",
                    "冒","映","星","昨","畏","趴","胃","贵","界","虹","虾","蚁","思","蚂","虽","品","咽","骂","哗",
                    "咱","响","哈","咬","咳","哪","炭","峡","罚","贱","贴","骨","钞","钟","钢","钥","钩","卸","缸",
                    "拜","看","矩","怎","牲","选","适","秒","香","种","秋","科","重","复","竿","段","便","俩","贷",
                    "顺","修","保","促","侮","俭","俗","俘","信","皇","泉","鬼","侵","追","俊","盾","待","律","很",
                    "须","叙","剑","逃","食","盆","胆","胜","胞","胖","脉","勉","狭","狮","独","狡","狱","狠","贸",
                    "怨","急","饶","蚀","饺","饼","弯","将","奖","哀","亭","亮","度","迹","庭","疮","疯","疫","疤",
                    "姿","亲","音","帝","施","闻","阀","阁","差","养","美","姜","叛","送","类","迷","前","首","逆",
                    "总","炼","炸","炮","烂","剃","洁","洪","洒","浇","浊","洞","测","洗","活","派","洽","染","济",
                    "洋","洲","浑","浓","津","恒","恢","恰","恼","恨","举","觉","宣","室","宫","宪","突","穿","窃",
                    "客","冠","语","扁","袄","祖","神","祝","误","诱","说","诵","垦","退","既","屋","昼","费","陡",
                    "眉","孩","除","险","院","娃","姥","姨","姻","娇","怒","架","贺","盈","勇","怠","柔","垒","绑",
                    "绒","结","绕","骄","绘","给","络","骆","绝","绞","统","耕","耗","艳","泰","珠","班","素","蚕",
                    "顽","盏","匪","捞","栽","捕","振","载","赶","起","盐","捎","捏","埋","捉","捆","捐","损","都",
                    "哲","逝","捡","换","挽","热","恐","壶","挨","耻","耽","恭","莲","莫","荷","获","晋","恶","真",
                    "框","桂","档","桐","株","桥","桃","格","校","核","样","根","索","哥","速","逗","栗","配","翅",
                    "辱","唇","夏","础","破","原","套","逐","烈","殊","顾","轿","较","顿","毙","致","柴","桌","虑",
                    "监","紧","党","晒","眠","晓","鸭","晃","晌","晕","蚊","哨","哭","恩","唤","啊","唉","罢","峰",
                    "圆","贼","贿","钱","钳","钻","铁","铃","铅","缺","氧","特","牺","造","乘","敌","秤","租","积",
                    "秧","秩","称","秘","透","笔","笑","笋","债","借","值","倚","倾","倒","倘","俱","倡","候","俯",
                    "倍","倦","健","臭","射","躬","息","徒","徐","舰","舱","般","航","途","拿","爹","爱","颂","翁",
                    "脆","脂","胸","胳","脏","胶","脑","狸","狼","逢","留","皱","饿","恋","桨","浆","衰","高","席",
                    "准","座","脊","症","病","疾","疼","疲","效","离","唐","资","凉","站","剖","竞","部","旁","旅",
                    "畜","阅","羞","瓶","拳","粉","料","益","兼","烤","烘","烦","烧","烛","烟","递","涛","浙","涝",
                    "酒","涉","消","浩","海","涂","浴","浮","流","润","浪","浸","涨","烫","涌","悟","悄","悔","悦",
                    "害","宽","家","宵","宴","宾","窄","容","宰","案","请","朗","诸","读","扇","袜","袖","袍","被",
                    "祥","课","谁","调","冤","谅","谈","谊","剥","恳","展","剧","屑","弱","陵","陶","陷","陪","娱",
                    "娘","通","能","难","预","桑","绢","绣","验","继","球","理","捧","堵","描","域","掩","捷","排",
                    "掉","堆","推","掀","授","教","掏","掠","培","接","控","探","据","掘","职","基","著","勒","黄",
                    "萌","萝","菌","菜","萄","菊","萍","菠","营","械","梦","梢","梅","检","梳","梯","桶","救","副",
                    "票","戚","爽","聋","袭","盛","雪","辅","辆","虚","雀","堂","常","匙","晨","睁","眯","眼","悬",
                    "野","啦","晚","啄","距","跃","略","蛇","累","唱","患","唯","崖","崭","崇","圈","铜","铲","银",
                    "甜","梨","犁","移","笨","笼","笛","符","第","敏","做","袋","悠","偿","偶","偷","您","售","停",
                    "偏","假","得","衔","盘","船","斜","盒","鸽","悉","欲","彩","领","脚","脖","脸","脱","象","够",
                    "猜","猪","猎","猫","猛","馅","馆","凑","减","毫","麻","痒","痕","廊","康","庸","鹿","盗","章",
                    "竟","商","族","旋","望","率","着","盖","粘","粗","粒","断","剪","兽","清","添","淋","淹","渠",
                    "渐","混","渔","淘","液","淡","深","婆","梁","渗","情","惜","惭","悼","惧","惕","惊","惨","惯",
                    "寇","寄","宿","窑","密","谋","谎","祸","谜","逮","敢","屠","弹","随","蛋","隆","隐","婚","婶",
                    "颈","绩","绪","续","骑","绳","维","绵","绸","绿","琴","斑","替","款","堪","搭","塔","越","趁",
                    "趋","超","提","堤","博","揭","喜","插","揪","搜","煮","援","裁","搁","搂","搅","握","揉","斯",
                    "期","欺","联","散","惹","葬","葛","董","葡","敬","葱","落","朝","辜","葵","棒","棋","植","森",
                    "椅","椒","棵","棍","棉","棚","棕","惠","惑","逼","厨","厦","硬","确","雁","殖","裂","雄","暂",
                    "雅","辈","悲","紫","辉","敞","赏","掌","晴","暑","最","量","喷","晶","喇","遇","喊","景","践",
                    "跌","跑","遗","蛙","蛛","蜓","喝","喂","喘","喉","幅","帽","赌","赔","黑","铸","铺","链","销",
                    "锁","锄","锅","锈","锋","锐","短","智","毯","鹅","剩","稍","程","稀","税","筐","等","筑","策",
                    "筛","筒","答","筋","筝","傲","傅","牌","堡","集","焦","傍","储","奥","街","惩","御","循","艇",
                    "舒","番","释","禽","腊","脾","腔","鲁","猾","猴","然","馋","装","蛮","就","痛","童","阔","善",
                    "羡","普","粪","尊","道","曾","焰","港","湖","渣","湿","温","渴","滑","湾","渡","游","滋","溉",
                    "愤","慌","惰","愧","愉","慨","割","寒","富","窜","窝","窗","遍","裕","裤","裙","谢","谣","谦",
                    "属","屡","强","粥","疏","隔","隙","絮","嫂","登","缎","缓","编","骗","缘","瑞","魂","肆","摄",
                    "摸","填","搏","塌","鼓","摆","携","搬","摇","搞","塘","摊","蒜","勤","鹊","蓝","墓","幕","蓬",
                    "蓄","蒙","蒸","献","禁","楚","想","槐","榆","楼","概","赖","酬","感","碍","碑","碎","碰","碗",
                    "碌","雷","零","雾","雹","输","督","龄","鉴","睛","睡","睬","鄙","愚","暖","盟","歇","暗","照",
                    "跨","跳","跪","路","跟","遣","蛾","蜂","嗓","置","罪","罩","错","锡","锣","锤","锦","键","锯",
                    "矮","辞","稠","愁","筹","签","简","毁","舅","鼠","催","傻","像","躲","微","愈","遥","腰","腥",
                    "腹","腾","腿","触","解","酱","痰","廉","新","韵","意","粮","数","煎","塑","慈","煤","煌","满",
                    "漠","源","滤","滥","滔","溪","溜","滚","滨","粱","滩","慎","誉","塞","谨","福","群","殿","辟",
                    "障","嫌","嫁","叠","缝","缠","静","碧","璃","墙","撇","嘉","摧","截","誓","境","摘","摔","聚",
                    "蔽","慕","暮","蔑","模","榴","榜","榨","歌","遭","酷","酿","酸","磁","愿","需","弊","裳","颗",
                    "嗽","蜻","蜡","蝇","蜘","赚","锹","锻","舞","稳","算","箩","管","僚","鼻","魄","貌","膜","膊",
                    "膀","鲜","疑","馒","裹","敲","豪","膏","遮","腐","瘦","辣","竭","端","旗","精","歉","熄","熔",
                    "漆","漂","漫","滴","演","漏","慢","寨","赛","察","蜜","谱","嫩","翠","熊","凳","骡","缩","慧",
                    "撕","撒","趣","趟","撑","播","撞","撤","增","聪","鞋","蕉","蔬","横","槽","樱","橡","飘","醋",
                    "醉","震","霉","瞒","题","暴","瞎","影","踢","踏","踩","踪","蝶","蝴","嘱","墨","镇","靠","稻",
                    "黎","稿","稼","箱","箭","篇","僵","躺","僻","德","艘","膝","膛","熟","摩","颜","毅","糊","遵",
                    "潜","潮","懂","额","慰","劈","操","燕","薯","薪","薄","颠","橘","整","融","醒","餐","嘴","蹄",
                    "器","赠","默","镜","赞","篮","邀","衡","膨","雕","磨","凝","辨","辩","糖","糕","燃","澡","激",
                    "懒","壁","避","缴","戴","擦","鞠","藏","霜","霞","瞧","蹈","螺","穗","繁","辫","赢","糟","糠",
                    "燥","臂","翼","骤","鞭","覆","蹦","镰","翻","鹰","警","攀","蹲","颤","瓣","爆","疆","壤","耀",
                    "躁","嚼","嚷","籍","魔","灌","蠢","霸","露","囊","罐"];
     
            $surNameLen = count($surName);
            $doubleSurNameLen = count($doubleSurName);
            $wordLen = count($word);
            $name = '';
            if($simple){
                $r = mt_rand(0,$surNameLen);
                $name .= $surName[$r];
                for ($i = 0; $i < $len – 1; $i++) {
                    $ra = mt_rand(0,$wordLen);
                    $name .= $word[$ra];
                }
            }else{
                $r = mt_rand(0,$doubleSurNameLen);
                $name .= $doubleSurName[$r];
                for ($i = 0; $i < $len – 2; $i++) {
                    $ra = mt_rand(0,$wordLen);
                    $name .= $word[$ra];
                }
            }
            
            $rs[‘info’][‘name’] = $name;
            return $rs;
        }

  • 密码保护:π框架SQL操作示例

    此内容受密码保护。如需查阅,请在下方输入密码。