UUID

百度百科的链接:https://baike.baidu.com/item/UUID/5921266

UUID 的目的是让分布式系统中的所有元素,都能有唯一的辨识资讯。

UUID 能用完吗?UUID是由一组32位数的16进制数字所构成,是故UUID理论上的总数为16^32=2^128,约等于3.4 x 10^38。也就是说若每纳秒产生1兆个UUID,要花100亿年才会将所有UUID用完。

UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的32个字符。示例:
  • 550e8400-e29b-41d4-a716-446655440000
    PHP 怎么产生呢?

    function uuid($prefix = ''){
       $chars = md5(uniqid(mt_rand(), true));
       $uuid  = substr($chars,0,8) . '-';
       $uuid .= substr($chars,8,4) . '-';
       $uuid .= substr($chars,12,4) . '-';
       $uuid .= substr($chars,16,4) . '-';
       $uuid .= substr($chars,20,12);
       return $prefix . $uuid;
    }

    我平时习惯这样产生32位的:

    function actId($attach=''){
        $str = uniqid(rand(), true);
        $str .= $attach;
        return md5($str);
    }

    我们平时做API的时候经常会用到token,下面方法会生成一个40位的token

    function setToken(){
       $str = md5(uniqid(md5(microtime(true)),true));
       $str = sha1($str);
       return $str;
    }

理解HTTP幂等性

本文转自网络

基于HTTP协议的Web API是时下最为流行的一种分布式服务提供方式。无论是在大型互联网应用还是企业级架构中,我们都见到了越来越多的SOA或RESTful的Web API。为什么Web API如此流行呢?我认为很大程度上应归功于简单有效的HTTP协议。HTTP协议是一种分布式的面向资源的网络应用层协议,无论是服务器端提供Web服务,还是客户端消费Web服务都非常简单。再加上浏览器、Javascript、AJAX、JSON以及HTML5等技术和工具的发展,互联网应用架构设计表现出了从传统的PHP、JSP、ASP.NET等服务器端动态网页向Web API + RIA(富互联网应用)过渡的趋势。Web API专注于提供业务服务,RIA专注于用户界面和交互设计,从此两个领域的分工更加明晰。在这种趋势下,Web API设计将成为服务器端程序员的必修课。然而,正如简单的Java语言并不意味着高质量的Java程序,简单的HTTP协议也不意味着高质量的Web API。要想设计出高质量的Web API,还需要深入理解分布式系统及HTTP协议的特性。

幂等性定义

本文所要探讨的正是HTTP协议涉及到的一种重要性质:幂等性(Idempotence)。在HTTP/1.1规范中幂等性的定义是:

Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

从定义上看,HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。幂等性属于语义范畴,正如编译器只能帮助检查语法错误一样,HTTP规范也没有办法通过消息格式等语法手段来定义它,这可能是它不太受到重视的原因之一。但实际上,幂等性是分布式系统设计中十分重要的概念,而HTTP的分布式本质也决定了它在HTTP中具有重要地位。

分布式事务 vs 幂等设计

为什么需要幂等性呢?我们先从一个例子说起,假设有一个从账户取钱的远程API(可以是HTTP的,也可以不是),我们暂时用类函数的方式记为:

bool withdraw(account_id, amount)

withdraw的语义是从account_id对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失败则返回false,账户余额不变。值得注意的是:和本地环境相比,我们不能轻易假设分布式环境的可靠性。一种典型的情况是withdraw请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被掉丢了,导致客户端无法得知处理结果。如果是在网页上,一些不恰当的设计可能会使用户认为上一次操作失败了,然后刷新页面,这就导致了withdraw被调用两次,账户也被多扣了一次钱。如图1所示:

non-idempotent

图1

这个问题的解决方案一是采用分布式事务,通过引入支持分布式事务的中间件来保证withdraw功能的事务性。分布式事务的优点是对于调用者很简单,复杂性都交给了中间件来管理。缺点则是一方面架构太重量级,容易被绑在特定的中间件上,不利于异构系统的集成;另一方面分布式事务虽然能保证事务的ACID性质,而但却无法提供性能和可用性的保证。

另一种更轻量级的解决方案是幂等设计。我们可以通过一些技巧把withdraw变成幂等的,比如:

int create_ticket() 
bool idempotent_withdraw(ticket_id, account_id, amount)

create_ticket的语义是获取一个服务器端生成的唯一的处理号ticket_id,它将用于标识后续的操作。idempotent_withdraw和withdraw的区别在于关联了一个ticket_id,一个ticket_id表示的操作至多只会被处理一次,每次调用都将返回第一次调用时的处理结果。这样,idempotent_withdraw就符合幂等性了,客户端就可以放心地多次调用。

基于幂等性的解决方案中一个完整的取钱流程被分解成了两个步骤:1.调用create_ticket()获取ticket_id;2.调用idempotent_withdraw(ticket_id, account_id, amount)。虽然create_ticket不是幂等的,但在这种设计下,它对系统状态的影响可以忽略,加上idempotent_withdraw是幂等的,所以任何一步由于网络等原因失败或超时,客户端都可以重试,直到获得结果。如图2所示:

idempotent

图2

和分布式事务相比,幂等设计的优势在于它的轻量级,容易适应异构环境,以及性能和可用性方面。在某些性能要求比较高的应用,幂等设计往往是唯一的选择。

HTTP的幂等性

HTTP协议本身是一种面向资源的应用层协议,但对HTTP协议的使用实际上存在着两种不同的方式:一种是RESTful的,它把HTTP当成应用层协议,比较忠实地遵守了HTTP协议的各种规定;另一种是SOA的,它并没有完全把HTTP当成应用层协议,而是把HTTP协议作为了传输层协议,然后在HTTP之上建立了自己的应用层协议。本文所讨论的HTTP幂等性主要针对RESTful风格的,不过正如上一节所看到的那样,幂等性并不属于特定的协议,它是分布式系统的一种特性;所以,不论是SOA还是RESTful的Web API设计都应该考虑幂等性。下面将介绍HTTP GET、DELETE、PUT、POST四种主要方法的语义和幂等性。

HTTP GET方法用于获取资源,不应有副作用,所以是幂等的。比如:GET http://www.bank.com/account/123456,不会改变资源的状态,不论调用一次还是N次都没有副作用。请注意,这里强调的是一次和N次具有相同的副作用,而不是每次GET的结果相同。GET http://www.news.com/latest-news这个HTTP请求可能会每次得到不同的结果,但它本身并没有产生任何副作用,因而是满足幂等性的。

HTTP DELETE方法用于删除资源,有副作用,但它应该满足幂等性。比如:DELETE http://www.forum.com/article/4231,调用一次和N次对系统产生的副作用是相同的,即删掉id为4231的帖子;因此,调用者可以多次调用或刷新页面而不必担心引起错误。

比较容易混淆的是HTTP POST和PUT。POST和PUT的区别容易被简单地误认为“POST表示创建资源,PUT表示更新资源”;而实际上,二者均可用于创建资源,更为本质的差别是在幂等性方面。在HTTP规范中对POST和PUT是这样定义的:

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line …… If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header.

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

POST所对应的URI并非创建的资源本身,而是资源的接收者。比如:POST http://www.forum.com/articles的语义是在http://www.forum.com/articles下创建一篇帖子,HTTP响应中应包含帖子的创建状态以及帖子的URI。两次相同的POST请求会在服务器端创建两份资源,它们具有不同的URI;所以,POST方法不具备幂等性。而PUT所对应的URI是要创建或更新的资源本身。比如:PUT http://www.forum/articles/4231的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有幂等性。

在介绍了几种操作的语义和幂等性之后,我们来看看如何通过Web API的形式实现前面所提到的取款功能。很简单,用POST /tickets来实现create_ticket;用PUT /accounts/account_id/ticket_id?amount=xxx来实现idempotent_withdraw。值得注意的是严格来讲amount参数不应该作为URI的一部分,真正的URI应该是/accounts/account_id/ticket_id,而amount应该放在请求的body中。这种模式可以应用于很多场合,比如:论坛网站中防止意外的重复发帖。

总结

上面简单介绍了幂等性的概念,用幂等设计取代分布式事务的方法,以及HTTP主要方法的语义和幂等性特征。其实,如果要追根溯源,幂等性是数学中的一个概念,表达的是N次变换与1次变换的结果相同,有兴趣的读者可以从Wikipedia上进一步了解。

创建一个自动加载

  1. 在运行环境目录下创建一个文件夹 mkdir composer2
  2. 用composer 初始化:
    cd composer2
    composer init   根据提示输入相应的信息 然后初始化成功,看到目录下有composer.json
  3. vim composer.json
    加入:

    "autoload": {
        "psr-4": {
            "" : ""
        }
    }
  4. composer install
  5. 然后新建一个控制器类 如下图:
  6. 在控制器类写入测试代码
  7. 在composer2目录下创建入口文件index.php 编写代码:
    <?php
       require __DIR__.'/./vendor/autoload.php';
       $student = new \app\controllers\StudentController()
  8. 运行一下,没有报错吧,实现了自动加载

从PHP5.3到PHP7.1发生了哪些变化

本文来源于PHP官方文档

PHP 5.3

  • 添加了命名空间的支持.
  • 添加了静态晚绑定支持.
  • 添加了跳标签支持.
  • 添加了原生的闭包(Lambda/匿名函数)支持.
  • 新增了两个魔术方法, __callStatic 和 __invoke.
  • 添加了 Nowdoc 语法支持, 类似于 Heredoc 语法, 但是包含单引号.
  • 使用 Heredoc 来初始化静态变量和类属性/常量变为可能.
  • 可使用双引号声明 Heredoc, 补充了 Nowdoc 语法.
  • 可在类外部使用 const 关键词声明 常量.
  • 三元运算操作符有了简写形式: ?:.
  • HTTP 流包裹器将从 200 到 399 全部的状态码都视为成功。
  • 动态访问静态方法变为可能.
  • 异常可以被内嵌.
  • 新增了循环引用的垃圾回收器并且默认是开启的.
  • mail() 现在支持邮件发送日志. (注意: 仅支持通过该函数发送的邮件.)

PHP 5.4

  • 新增支持 traits 。
  • 新增短数组语法,比如 $a = [1, 2, 3, 4]; 或 $a = [‘one’ => 1, ‘two’ => 2, ‘three’ => 3, ‘four’ => 4]; 。
  • 新增支持对函数返回数组的成员访问解析,例如 foo()[0] 。
  • 现在 闭包 支持 $this 。
  • 现在不管是否设置 short_open_tag php.ini 选项,<?= 将总是可用。
  • 新增在实例化时访问类成员,例如: (new Foo)->bar() 。
  • 现在支持 Class::{expr}() 语法。
  • 新增二进制直接量,例如:0b001001101 。
  • 改进解析错误信息和不兼容参数的警告。
  • SESSION 扩展现在能追踪文件的 上传进度 。
  • 内置用于开发的 CLI 模式的 web server 。

PHP5.5

  • 新增 Generators
  • 新增 finally 关键字
  • foreach 现在支持 list()
  • empty() 支持任意表达式
  • array and string literal dereferencing ¶
  • 新的密码哈希 API
  • 改进 GD

PHP5.6

  • 使用表达式定义常量
  • 使用 … 运算符定义变长参数函数
  • 使用 … 运算符进行参数展开
  • 使用 ** 进行幂运算
  • use function 以及 use const
  • phpdbg
  • 默认字符编码
  • php://input 是可重用的了
  • 大文件上传(现在可以支持大于 2GB 的文件上传)
  • GMP 支持运算符重载
  • 使用 hash_equals() 比较字符串避免时序攻击
  • __debugInfo()
  • gost-crypto 散列算法
  • SSL/TLS 提升
  • pgsql 异步支持

PHP7.0

  • 标量类型声明
  • 返回值类型声明
  • null合并运算符
  • 太空船操作符(组合比较符)
  • 通过 define() 定义常量数组
  • 匿名类
  • Unicode codepoint 转译语法
  • Closure::call()
  • 为unserialize()提供过滤
  • IntlChar
  • 预期
  • Group use declarations
  • 生成器可以返回表达式
  • Generator delegation
  • 整数除法函数 intp()
  • 会话选项
  • preg_replace_callback_array()
  • CSPRNG Functions
  • 可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象
  • 其他特性

PHP7.1

  • 可为空(Nullable)类型
  • Void 函数
  • Symmetric array destructuring
  • 类常量可见性
  • iterable 伪类
  • 多异常捕获处理
  • list()现在支持键名
  • 支持为负的字符串偏移量
  • ext/openssl 支持 AEAD
  • 通过 Closure::fromCallable() 将callables转为闭包
  • 异步信号处理
  • HTTP/2 server push support in ext/curl

以上就是从PHP5.3到PHP7.1发生了哪些变化的详细内容,更多请关注php中文网其它相关文章!

laravel Artisan的使用

  • Artisan 是laravel 中自带的命令行工具的名称
  • 由强大的Symfony  Console组件驱动的
  • 提供了一些对应用开发有帮助的命令
  • 查看所有可用的 Artisan命令:php artisan 或 php artisan list
  • 查看命令的帮助信息:php artisan help XXX
    例:比如我们要查询迁移这个命令的使用方法:php artisan help migrate
    例:查询如果使用make model :php artisan help make:model

Artisan基本使用
查看laravel 版本:php artisan –version
查看所有路由:php artisan route:list
Artisan 功能使用:
创建控制器:php artisan make:controller StudentConller
创建模型:php artisan make:model Student
创建中间件:php artisan make:middleware Activity
生成auth: php artisan make:auth  然后使用迁移命令:php artisan migrate 看下数据库里面是不是生成了表(要先去env里面配置下数据库信息哦)

新建迁移文件

新建一个students 表的迁移文件
php artisan make:migration create_students_table(迁移文件的名字)
例:php artisan make:migration create_students_table –create=students
([maɪˈgreɪʃn]迁移,移居)

生成模型的同时生成迁移文件
php artisan make:model Student -m
例子:php artisan make:model Article -m

前面我们创建好的迁移文件 Student迁移文件 如下图

修改下 迁移文件 加上我们需要的自动 然后执行

php artisan migrate 完成迁移

数据填充

1.创建一个填充文件,并完善填充文件
php artisan make:seeder StudentTableSeeder

2.执行单个填充文件
php artisan db:seed –class=StudentTableSeeder
成功后看下数据库

3.批量执行填充文件
修改下DatabaseSeeder.php文件

php artisan db:seed

composer的使用

  1. 新建一个目录使用命令:composer init 初始化 按照提示输入初始需要的名称等信息
  2. composer search XXXXX  搜索 例:composer search phpmailer
  3. composer show –all XXXXX 列出所有可用的软件包  例:composer show –all phpmailer/phpmailer
  4. composer require XXXX  安装新的依赖包,并将依赖写入当前目录的 composer.json 文件中 例:composer require phpmailer/phpmailer
  5. composer install 依据当前目录下的 composer.lock(锁文件) 或 composer.json 文件,所定义的依赖关系,安装依赖包。(比如修改composer.json后,可用执行composer install 执行安装)
  6. composer update 更新依赖版本或者修改了composer.json 可用执行update命令
  7. composer config –lists 查看composer的配置信息
    学会上面这些命令 用composer 安装laravel yii2 tp5等是不是很容易了
  8. 如果还是不太明白 网上搜了一个视频可用参考下:https://www.imooc.com/learn/702 第一章有讲解composer的基本用法

ORM是什么?如何理解ORM

本文转自网络

一、ORM简介
对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。那么,到底如何实现持久化呢?一种简单的方案是采用硬编码方式,为每一种可能的数据库访问操作提供单独的方法。
这种方案存在以下不足:
1.持久化层缺乏弹性。一旦出现业务需求的变更,就必须修改持久化层的接口
2.持久化层同时与域模型与关系数据库模型绑定,不管域模型还是关系数据库模型发生变化,毒药修改持久化曾的相关程序代码,增加了软件的维护难度。

ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。Java典型的ORM中间件有:Hibernate,ibatis,speedframework。
ORM的方法论基于三个核心原则:
· 简单:以最基本的形式建模数据。
· 传达性:数据库结构被任何人都能理解的语言文档化。
· 精确性:基于数据模型创建正确标准化了的结构。

二、ORM的概念
让我们从O/R开始。字母O起源于”对象”(Object),而R则来自于”关系”(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。
当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。

ORM解决的主要问题是对象关系的映射。域模型和关系模型分别是建立在概念模型的基础上的。域模型是面向对象的,而关系模型是面向关系的。一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录,类的每个属性对应表的每个字段。
ORM技术特点:
1.提高了开发效率。由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。
2.ORM提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据。

三、ORM的优缺点
ORM的缺点是会牺牲程序的执行效率和会固定思维模式。
从系统结构上来看,采用ORM的系统一般都是多层系统,系统的层次多了,效率就会降低。ORM是一种完全的面向对象的做法,而面向对象的做法也会对性能产生一定的影响。

在我们开发系统时,一般都有性能问题。性能问题主要产生在算法不正确和与数据库不正确的使用上。ORM所生成的代码一般不太可能写出很高效的算法,在数据库应用上更有可能会被误用,主要体现在对持久对象的提取和和数据的加工处理上,如果用上了ORM,程序员很有可能将全部的数据提取到内存对象中,然后再进行过滤和加工处理,这样就容易产生性能问题。
在对对象做持久化时,ORM一般会持久化所有的属性,有时,这是不希望的。
但ORM是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。但我们不能指望工具能一劳永逸的解决所有问题,有些问题还是需要特殊处理的,但需要特殊处理的部分对绝大多数的系统,应该是很少的。

phpstrom 添加laravel智能提示

用laravel的时候发现 phpstrom并不能很好智能提示于是度娘上搜了一下,方法如下:

  1. 先在phpstrom 中添加插件 如下图 (我的机子已经装过)
  2. composer 安装 barryvdh/laravel-ide-helper
    直接在terminal中执行: composer require barryvdh/laravel-ide-helper
    耐心等待一会
  3. 安装成功后,在 项目中的 conifg/app.php 的providers的数组中添加类的支持

    Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
  4. 重启phpstrom 已经完美提示laravel

laravel 安装

laravel 中文网站: https://www.golaravel.com/

安装方式一:下载安装

  1. 下载
    可以从github上下载 官方开源地址:https://github.com/laravel/laravel/ 默认打开是 master分支 最新版本,可以选择你需要的版本点击 右边 clone or download 即可
  2. 安装
    放在web运行目录 指向public 目录,
    (1)如果出现错误“failed to open stream: No such file or directory in /bootstrap/autoload.php”  在laravel目录下 运行 composer install  然后抽支烟或者喝杯咖啡,静静等一会,要点时间的…… (如果composer 还没安装,那需要先安装下composer哦)
    (2)如果出现:“Whoops, looks like something went wrong.”按照下面方法操作
    1.开启调试模式
    打开项目目录下config/app.php修改:
    ‘debug’ => env(‘APP_DEBUG’, true)
    2.修改根目录.env.example文件为.env: mv .env.example .env
    3.执行命令生成key
    php artisan key:generate
    结果出现 set successfully.
    执行好后,查看下.env文件 看看生成的key 是不是在文件里面啦,现在刷新页面试试,看到了帅气的

    安装方式二:通过composer  create-project 安装

    laravel 为什么可以通过composer安装呢?因为composer里有laravel包
    在要安装的WEB目录下输入命令: composer create-project –prefer-dist laravel/laravel laravel_test(laravel_test 是你要安装的目录名称 可以自己定义)
    耐心等待一会就安装成功了
    我本地MAC环境PHP 是5.6.3的 所以选择的5.2版本安装的

     

 

mac 下composer 安装

方式一:mac下可以使用

brew install composer

方式二:官方安装命令

php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"

执行第一条命令下载下来的 composer-setup.php 脚本将简单地检测 php.ini 中的参数设置,如果某些参数未正确设置则会给出警告;然后下载最新版本的 composer.phar 文件到当前目录。

上述 3 条命令的作用依次是:

  1. 下载安装脚本 - composer-setup.php - 到当前目录。
  2. 执行安装过程。
  3. 删除安装脚本。

    局部安装

    上述下载 Composer 的过程正确执行完毕后,可以将 composer.phar 文件复制到任意目录(比如项目根目录下),然后通过 php composer.phar 指令即可使用 Composer 了!

    全局安装

    全局安装是将 Composer 安装到系统环境变量 PATH 所包含的路径下面,然后就能够在命令行窗口中直接执行 composer 命令了。

    Mac 或 Linux 系统:

    打开命令行窗口并执行如下命令将前面下载的 composer.phar 文件移动到 /usr/local/bin/ 目录下面:

    复制
    sudo mv composer.phar /usr/local/bin/composer
    

    Mac 或 Linux 系统:

    打开命令行窗口并执行如下命令将前面下载的 composer.phar 文件移动到 /usr/local/bin/ 目录下面:

    复制
    sudo mv composer.phar /usr/local/bin/composer
    

     如果使用中国全量镜像?打开终端输入以下命令即可

    composer config -g repo.packagist composer https://packagist.phpcomposer.com
  4. 使用composer 的时候 我经常使用家里宽带网络报错( failed to open stream),换成4G 就能顺利使用,镜像还是不稳定吧。