好听的音乐

音乐zkbhj 发表了文章 • 0 个评论 • 2973 次浏览 • 2016-12-19 11:15 • 来自相关话题

【网络风格】
1、六哲 - 爱是一种责任 http://music.zkbhj.com/?goto=listen&id=380
 
【纯音乐】
1、悲伤的天使 http://music.zkbhj.com/?goto=listen&id=389 查看全部
【网络风格】
1、六哲 - 爱是一种责任 http://music.zkbhj.com/?goto=listen&id=380
 
【纯音乐】
1、悲伤的天使 http://music.zkbhj.com/?goto=listen&id=389

PHP开发者需要了解的Composer

专业名词zkbhj 发表了文章 • 0 个评论 • 1331 次浏览 • 2016-12-17 17:52 • 来自相关话题

Composer是一个非常流行的PHP包依赖管理工具,已经取代PEAR包管理器,对于PHP开发者来说掌握Composer是必须的.

对于使用者来说Composer非常的简单,通过简单的一条命令将需要的代码包下载到vendor目录下,然后开发者就可以引入包并使用了.
其中的关键在于你项目定义的composer.json,可以定义项目需要依赖的包(可能有多个),而依赖的包可能又依赖其他的包(这就是组件的好处),这些都不用你烦心,Composer会自动下载你需要的一切,一切在于composer.json的定义.

Composer对于使用者来说是很透明,但是其背后的理念还是需要了解一下的,其的诞生也不是偶然的,得益于Github的快速发展,PHP语言也越来越现代化,显得更高大上了.

为了理解Composer,先大概了解下其结构:

Composer的结构

Composer命令行工具:
这个理解就比较简单了,通过使用者定义的Composer.json去下载你需要的代码,假如只是简单的使用Composer,那么掌握一些具体命令就完全可以了
Autoloading代码加载器:
通过Composer,开发者可以通过多种方式去使用,而其中的关键在于PHP的命名空间概念,以及PSR-4标准的发展,Composer只是根据这二者开发了一个代码自动加载器
Github:
有了Github,PHP开发人员可以将开源的代码托管在这上面,而Composer的发展源于Github,Composer本质上就是将Github上的代码下载到本地.
Packagist:
对于使用者来说使用的是Composer的命令行工具,那么命令行工具怎么知道有多少包可以被用户使用呢,这主要就是依赖于Packagist,Packagist是Composer主要的一个包信息存储库,包开发者将具体代码托管到Github上,将包信息提交到Packagist上,这样使用者就可以通过Composer去使用.
Composer根据本地定义的composer.json信息去查询Packagist,Packagist根据Composer.json/Package.json信息解析,最终对应到github仓库,Composer最终下载代码的时候还要依赖于Github仓库上的Composer.json,这里涉及到三种类型的composer.json,含义是不一样的.
Composer.json:
这是Composer的核心,是Composer的规则,上面也提到了三种类型的Composer.json,在使用的时候一定要注意区分,我初学的时候就总是搞乱.

Composer命令行工具

composer init
使用者可以在自己的项目下创建composer.json以便定义你项目的依赖包,也可以通过composer init交互式的创建composer.json.

composer install
应该是最常用的命令,composer会根据本地的composer.json安装包,将下载的包放入项目下的vendor目录下,同时将安装时候的包版本信息放入到composer.lock,以便锁定版本.
其实在install的时候,假如发现composer.lock版本和目前vendor目录下的代码版本是一致的,则Composer会什么也不做,composer.lock的目的就是让你安心在目前这个版本下工作,而不获取最新版本的包.

composer update
那么如何更新composer.lock以便获取到最新版本的包呢?通过这个命令即可更新最新版本的包

composer config
这个命令还是建议了解下,全局的配置保存在COMPOSER_HOME/config.json,非全局的配置信息则存储在本项目目录下.
composer config --list -g
composer config -g notify-on-install false
composer global config bin-dir --absolutecomposer create-project
这个命令不常用,但是个人觉得还是很重要的,使用普通的install命令是将项目所有的依赖包下载到本项目vendor目录下.而通过这个命令则是将所有的代码及其依赖的包放到一个目录下,相当于执行了一个git clone命令,一般是包的开发者可能为了修复bug会使用该命令.

composer global
这是一个全局的安装命令,它允许你在COMPOSER_HOME目录下执行Composer的命令,比如install,update.当然你的COMPOSER_HOME要在$PATH环境下.

比如执行composer global require fabpot/php-cs-fixer,现在php-cs-fixer命令行可以全局运行了,如果稍后想更新它,只需要运行composer global update

composer dump-autoload
当你修改项目下的composer.json的文件,并不一定要运行composer update命令进行更新,有的时候可以使用该命令来更新加载器,比如你要引用本地自定义的包(不是来自于packagist),后面会通过实践来说明该命令.

composer require
假如手动或者交互式创建composer.json文件,可以直接使用该命令来安装包composer require cerdic/css-tidy:1.5.2
composer require "ywdblog/phpcomposer:dev-master"–prefer-source和–prefer-dist参数
–prefer-dist:对于稳定的包来说,一般Composer安装默认使用该参数,这也能加快安装,比如有可能直接从packagist安装了相应的包,而不用实际去Github上下载包.
–prefer-source:假如使用该参数,则会直接从Github上安装,安装包后vendor目录下还含有.git信息
 
composer require "ywdblog/phpcomposer:dev-master" --prefer-source
#在vendor/ywdblog/phpcomposer目录下含有.git信息
 如何给Composer添加代理
在国内使用Composer下载特别慢,可以通过二个方法进行加速

composer config repo.packagist composer "https://packagist.phpcomposer.com"
编辑composer.json"repositories": {
"packagist": {
"type": "composer",
"url": "https://packagist.phpcomposer.com"
}
}Autoloading代码加载器

composer本身集成一个autoloader,支持PSR-4,PSR-0,classmap,files autoloading.

这里通过一个例子来说明通过Composer如何引用classmap,files,本地符合PSR-4标准的代码

编辑composer.json
"autoload": {
"classmap": ["othsrc/","classsrc.php"],
"files": ["othsrc/filesrc.php"],
"psr-4": {"Foo\\Bar\\": "src"}
}composer dump-autoload
 
通过上述的操作,对于PSR-4来说等同注册了一个PSR-4 autoloader(从Foo\Bar命名空间)
假如不想使用Composer的autoloader,可以直接包含vendor/composer/autoload_*.php 文件,配置自己的加载器.
具体的例子托管在github上,可参考.

Repositories

关于Repositories,了解其不是必须的,但是假如掌握则更能理解Composer,对于Repositories,其中文文档和英文文档解释的很好,这里也进行了一些摘抄.

基本概念
包:
Composer是一个依赖管理工具,它在本地安装一些资源包和包的描述(比如包名称和对应的版本),比较重要的元数据描述是dist和source,dist指向一个存档,该存档是对一个资源包的某个版本的数据进行的打包.source指向一个开发中的源,这通常是一个源代码仓库(比如git)

资源库:
一个资源库是一个包的来源.它是一个packages/versions的列表.
Composer将查看所有你定义的repositories以找到项目需要的资源包(这句话很重要).
默认情况下已经将Packagist.org注册到Composer(或者理解为Packagist.org是Composer资源库默认的仓库类型)

Composer资源库类型
Composer资源库包括四种类型,默认的是composer类型,也就是packagist.org所使用的资源类型.
它使用一个单一的packages.json文件,包含了所有的资源包元数据.当你将包发布到pckagist.org上,则默认系统会创建一个packages.json,不过我没有找到我的包对应的文件.

VCS资源库类型
假如你想构建一个私有的Composer私有资源库类型,可以使用该类型,这里举一个例子,比如你在自己项目的composer.json定义如下,则就可以使用对应的Github上的代码了.{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/ywdblog/phpcomposer"
}
],
"require": {
"ywdblog/phpcomposer": "dev-master"
}
}当运行composer update的时候,Comoser实际上是从Github上下载包而不是从pckagist.org上下载.

另外假如需要使用Package资源库类型或者PEAR资源库类型,参考官方文档即可,一般在composer.json中定义name、version属性即可.

Composer.json

在本文上面也多次提到了composer.json,比如你希望使用第三方包则需要在本地定义composer.json,Composer安装第三方包后,也会在第三方包目录下发现composer.json,那么这二者都叫composer.json,有什么区别呢?理解这非常的重要.

假如你在自己的项目下面定义一个composer.json,则这个包称之为ROOT包,这个composer.json定义你项目需要的条件(比如你的项目可能依赖一个第三方包).

composer.json中有些属性只能被ROOT包使用,比如config属性只在ROOT包中生效.

一个资源包是不是ROOT包,取决于它的上下文,比如你git clone ywdblog/phpcomposer,则这时候本地phpcomposer目录就是ROOT包,假如你在本地phpcomposer目录下composer require ywdblog/phpcomposer,则这时候你的项目phpcomposer就是ROOT包.

了解composer-schema.json可参考该网址,Laravel作为一个成熟的框架,其定义的composer.json非常经典

关于包的版本
当使用者在本地配置composer.json的时候,可以指定需要包的特定版本,Composer支持从Github仓库中下载Tag或者分支下的包.

对于Github上的Tag来说,Packagist会创建对应包的版本,它符合X.Y.Z,vX.Y.Z,X.Y.Z-包类型,就是说Github上虽然只有一个特定版本的包,但Composer支持多种形式的引用方式,比如:composer require monolog/monolog 1.0.0-RC1
composer require monolog/monolog v1.0.0-RC1
composer require monolog/monolog 1.0.*
composer require monolog/monolog ~1.10
 对于Github上的分支来说,Packagist会创建对应包的版本,假如分支名看起来像一个版本,将创建{分支名}-dev的包版本号,如果分支名看起来不像一个版本号,它将会创建dev-{分支名}形式的版本号
 
composer require monolog/monolog master-dev
composer require monolog/monolog master.x-dev总结:
理解Composer,最重要的是实践,最后也能明白PSR-4和命名空间,也可以尝试将你的项目发布到pckagist.org上.


文/虞大胆(简书作者)
原文链接:http://www.jianshu.com/p/98c5b254a79e
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。 查看全部
Composer是一个非常流行的PHP包依赖管理工具,已经取代PEAR包管理器,对于PHP开发者来说掌握Composer是必须的.

对于使用者来说Composer非常的简单,通过简单的一条命令将需要的代码包下载到vendor目录下,然后开发者就可以引入包并使用了.
其中的关键在于你项目定义的composer.json,可以定义项目需要依赖的包(可能有多个),而依赖的包可能又依赖其他的包(这就是组件的好处),这些都不用你烦心,Composer会自动下载你需要的一切,一切在于composer.json的定义.

Composer对于使用者来说是很透明,但是其背后的理念还是需要了解一下的,其的诞生也不是偶然的,得益于Github的快速发展,PHP语言也越来越现代化,显得更高大上了.

为了理解Composer,先大概了解下其结构:

Composer的结构

Composer命令行工具:
这个理解就比较简单了,通过使用者定义的Composer.json去下载你需要的代码,假如只是简单的使用Composer,那么掌握一些具体命令就完全可以了
Autoloading代码加载器:
通过Composer,开发者可以通过多种方式去使用,而其中的关键在于PHP的命名空间概念,以及PSR-4标准的发展,Composer只是根据这二者开发了一个代码自动加载器
Github:
有了Github,PHP开发人员可以将开源的代码托管在这上面,而Composer的发展源于Github,Composer本质上就是将Github上的代码下载到本地.
Packagist:
对于使用者来说使用的是Composer的命令行工具,那么命令行工具怎么知道有多少包可以被用户使用呢,这主要就是依赖于Packagist,Packagist是Composer主要的一个包信息存储库,包开发者将具体代码托管到Github上,将包信息提交到Packagist上,这样使用者就可以通过Composer去使用.
Composer根据本地定义的composer.json信息去查询Packagist,Packagist根据Composer.json/Package.json信息解析,最终对应到github仓库,Composer最终下载代码的时候还要依赖于Github仓库上的Composer.json,这里涉及到三种类型的composer.json,含义是不一样的.
Composer.json:
这是Composer的核心,是Composer的规则,上面也提到了三种类型的Composer.json,在使用的时候一定要注意区分,我初学的时候就总是搞乱.

Composer命令行工具

composer init
使用者可以在自己的项目下创建composer.json以便定义你项目的依赖包,也可以通过composer init交互式的创建composer.json.

composer install
应该是最常用的命令,composer会根据本地的composer.json安装包,将下载的包放入项目下的vendor目录下,同时将安装时候的包版本信息放入到composer.lock,以便锁定版本.
其实在install的时候,假如发现composer.lock版本和目前vendor目录下的代码版本是一致的,则Composer会什么也不做,composer.lock的目的就是让你安心在目前这个版本下工作,而不获取最新版本的包.

composer update
那么如何更新composer.lock以便获取到最新版本的包呢?通过这个命令即可更新最新版本的包

composer config
这个命令还是建议了解下,全局的配置保存在COMPOSER_HOME/config.json,非全局的配置信息则存储在本项目目录下.
composer config --list -g
composer config -g notify-on-install false
composer global config bin-dir --absolute
composer create-project
这个命令不常用,但是个人觉得还是很重要的,使用普通的install命令是将项目所有的依赖包下载到本项目vendor目录下.而通过这个命令则是将所有的代码及其依赖的包放到一个目录下,相当于执行了一个git clone命令,一般是包的开发者可能为了修复bug会使用该命令.

composer global
这是一个全局的安装命令,它允许你在COMPOSER_HOME目录下执行Composer的命令,比如install,update.当然你的COMPOSER_HOME要在$PATH环境下.

比如执行composer global require fabpot/php-cs-fixer,现在php-cs-fixer命令行可以全局运行了,如果稍后想更新它,只需要运行composer global update

composer dump-autoload
当你修改项目下的composer.json的文件,并不一定要运行composer update命令进行更新,有的时候可以使用该命令来更新加载器,比如你要引用本地自定义的包(不是来自于packagist),后面会通过实践来说明该命令.

composer require
假如手动或者交互式创建composer.json文件,可以直接使用该命令来安装包
composer require  cerdic/css-tidy:1.5.2
composer require "ywdblog/phpcomposer:dev-master"
–prefer-source和–prefer-dist参数
–prefer-dist:对于稳定的包来说,一般Composer安装默认使用该参数,这也能加快安装,比如有可能直接从packagist安装了相应的包,而不用实际去Github上下载包.
–prefer-source:假如使用该参数,则会直接从Github上安装,安装包后vendor目录下还含有.git信息
 
composer require "ywdblog/phpcomposer:dev-master" --prefer-source 
#在vendor/ywdblog/phpcomposer目录下含有.git信息

 如何给Composer添加代理
在国内使用Composer下载特别慢,可以通过二个方法进行加速

composer config repo.packagist composer "https://packagist.phpcomposer.com"
编辑composer.json
"repositories": {
"packagist": {
"type": "composer",
"url": "https://packagist.phpcomposer.com"
}
}
Autoloading代码加载器

composer本身集成一个autoloader,支持PSR-4,PSR-0,classmap,files autoloading.

这里通过一个例子来说明通过Composer如何引用classmap,files,本地符合PSR-4标准的代码

编辑composer.json
"autoload": {
"classmap": ["othsrc/","classsrc.php"],
"files": ["othsrc/filesrc.php"],
"psr-4": {"Foo\\Bar\\": "src"}
}
composer dump-autoload
 
通过上述的操作,对于PSR-4来说等同注册了一个PSR-4 autoloader(从Foo\Bar命名空间)
假如不想使用Composer的autoloader,可以直接包含vendor/composer/autoload_*.php 文件,配置自己的加载器.
具体的例子托管在github上,可参考.

Repositories

关于Repositories,了解其不是必须的,但是假如掌握则更能理解Composer,对于Repositories,其中文文档和英文文档解释的很好,这里也进行了一些摘抄.

基本概念
包:
Composer是一个依赖管理工具,它在本地安装一些资源包和包的描述(比如包名称和对应的版本),比较重要的元数据描述是dist和source,dist指向一个存档,该存档是对一个资源包的某个版本的数据进行的打包.source指向一个开发中的源,这通常是一个源代码仓库(比如git)

资源库:
一个资源库是一个包的来源.它是一个packages/versions的列表.
Composer将查看所有你定义的repositories以找到项目需要的资源包(这句话很重要).
默认情况下已经将Packagist.org注册到Composer(或者理解为Packagist.org是Composer资源库默认的仓库类型)

Composer资源库类型
Composer资源库包括四种类型,默认的是composer类型,也就是packagist.org所使用的资源类型.
它使用一个单一的packages.json文件,包含了所有的资源包元数据.当你将包发布到pckagist.org上,则默认系统会创建一个packages.json,不过我没有找到我的包对应的文件.

VCS资源库类型
假如你想构建一个私有的Composer私有资源库类型,可以使用该类型,这里举一个例子,比如你在自己项目的composer.json定义如下,则就可以使用对应的Github上的代码了.
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/ywdblog/phpcomposer"
}
],
"require": {
"ywdblog/phpcomposer": "dev-master"
}
}
当运行composer update的时候,Comoser实际上是从Github上下载包而不是从pckagist.org上下载.

另外假如需要使用Package资源库类型或者PEAR资源库类型,参考官方文档即可,一般在composer.json中定义name、version属性即可.

Composer.json

在本文上面也多次提到了composer.json,比如你希望使用第三方包则需要在本地定义composer.json,Composer安装第三方包后,也会在第三方包目录下发现composer.json,那么这二者都叫composer.json,有什么区别呢?理解这非常的重要.

假如你在自己的项目下面定义一个composer.json,则这个包称之为ROOT包,这个composer.json定义你项目需要的条件(比如你的项目可能依赖一个第三方包).

composer.json中有些属性只能被ROOT包使用,比如config属性只在ROOT包中生效.

一个资源包是不是ROOT包,取决于它的上下文,比如你git clone ywdblog/phpcomposer,则这时候本地phpcomposer目录就是ROOT包,假如你在本地phpcomposer目录下composer require ywdblog/phpcomposer,则这时候你的项目phpcomposer就是ROOT包.

了解composer-schema.json可参考该网址,Laravel作为一个成熟的框架,其定义的composer.json非常经典

关于包的版本
当使用者在本地配置composer.json的时候,可以指定需要包的特定版本,Composer支持从Github仓库中下载Tag或者分支下的包.

对于Github上的Tag来说,Packagist会创建对应包的版本,它符合X.Y.Z,vX.Y.Z,X.Y.Z-包类型,就是说Github上虽然只有一个特定版本的包,但Composer支持多种形式的引用方式,比如:
composer require monolog/monolog  1.0.0-RC1 
composer require monolog/monolog v1.0.0-RC1
composer require monolog/monolog 1.0.*
composer require monolog/monolog ~1.10

 对于Github上的分支来说,Packagist会创建对应包的版本,假如分支名看起来像一个版本,将创建{分支名}-dev的包版本号,如果分支名看起来不像一个版本号,它将会创建dev-{分支名}形式的版本号
 
composer require monolog/monolog  master-dev
composer require monolog/monolog master.x-dev
总结:
理解Composer,最重要的是实践,最后也能明白PSR-4和命名空间,也可以尝试将你的项目发布到pckagist.org上.


文/虞大胆(简书作者)
原文链接:http://www.jianshu.com/p/98c5b254a79e
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Yii2.0中的Url::to(), Url::toRoute(), Url::current()用法总结

Yii框架zkbhj 发表了文章 • 0 个评论 • 1904 次浏览 • 2016-12-17 14:33 • 来自相关话题

[Url::current] 获取当前路径 
现在测试本地路径(http://daxia.dc.weixin.com/mobile/hmConnections/user/verify-user) 

a: //获取当前路径 - 相对路径
$url = Url::current();
举例:/mobile/hmConnections/user/verify-user
b: //获取当前路径 - 相对路径
$url = Url::current(['id' => 1], false);
例如: /mobile/hmConnections/user/verify-user?id=1
c: //获取当前路径 - 绝对路径
$url = Url::current(['id' => 1], true);
例如: http://daxia.dc.weixin.com/mob ... d%3D1
d: //获取当前路径 - 绝对路径 传输协议-http
$url = Url::current(['id' => 1], 'http');
例如: http://daxia.dc.weixin.com/mob ... d%3D1
e: //获取当前路径 - 绝对路径 传输协议-https
$url = Url::current(['id' => 1], 'https');
例如: https://daxia.dc.weixin.com/mobile/hmConnections/user/verify-user?id=1 
 

[Url::toRoute] 获取某一地址 
现在测试本地路径(http://daxia.dc.weixin.com/mobile/hmConnections/user/verify-user) 

1://获取某地址 - 相对路径
$url = Url::toRoute('site/index');
例如: /mobile/hmConnections/site/index
2://获取某地址 - 相对路径
$url = Url::toRoute('site/index', false);
例如: /mobile/hmConnections/site/index
说明: 等价于1 因为默认是false
3://获取某地址 - 相对路径
$url = Url::toRoute(['site/index', 'id' => 1]);
例如: /mobile/hmConnections/site/index?id=1
4://获取某地址的 - 绝对路径
$url = Url::toRoute('site/index', true);
例如: http://daxia.dc.weixin.com/mob ... index
5://获取某地址的 - 绝对路径
$url = Url::toRoute('site/index', ['id' => 1]);
例如: http://daxia.dc.weixin.com/mob ... index
说明: 参数没有输出,说明,这种写法['id' => 1], 他当成了true,所以等价于4
6://获取某地址的 - 绝对路径 (传输协议-http)
$url = Url::toRoute('site/index', 'http');
例如: https://daxia.dc.weixin.com/mo ... index
说明: 等价于4
7://获取某地址的 - 绝对路径 (传输协议-https)
$url = Url::toRoute('site/index', 'https');
例如: https://daxia.dc.weixin.com/mobile/hmConnections/site/index 

[Url::to] 创建一个基于给定参数的网址
现在测试本地路径(http://daxia.dc.weixin.com/mobile/hmConnections/user/verify-user) 

1): //获某网址 - 相对路径
$url = Url::to(['site/index']);
举例:/mobile/hmConnections/site/index
说明:等价于2
2): //获取网址(带参数) - 相对路径
$url = Url::to(['site/index', 'id' => 1]);
举例:/mobile/hmConnections/site/index?id=1
说明:等价于3
3): 获取当前路径 - 相对路径
$url = Url::to();
举例:/mobile/hmConnections/user/verify-user
等价于a
4): 获取url - 相对路径
$url = Url::to('@web/image/1.jpg');
举例: /image/a.jpg
说明:它将指定到你的某一个别名目录下@web
5): 获取url - 相对路径
$url = Url::to('image/1.jpg');
举例:image/a.jpg
6): 获取url - 绝对路径(@mobileUrl 自己配置好的)
$url = Url::to('@mobileUrl/image/1.jpg', true);
举例:http://daxia.dc.weixin.com/sta ... 1.jpg
7): //获取url - 绝对路径 (传输协议-https)
$url = Url::to('@mobileUrl/image/1.jpg', 'https');
举例:https://daxia.dc.weixin.com/st ... 1.jpg
8): //获取url - 绝对路径 (传输协议-http)
$url = Url::to('@mobileUrl/image/1.jpg', 'http');
举例:http://daxia.dc.weixin.com/sta ... 1.jpg
说明:等价于 6)

** 特别说明下:@mobileUrl
$url = Url::to('@mobileUrl/city-partner/city-partner/images/1.png');
- @mobileUrl,配置如下: Yii::setAlias('@mobileUrl', Yii::getAlias('@web/static/mobile/'));
* 给Yii::getAlias('@web/static/mobile/')定义一个别名@mobileUrl(
也就是,下次我们直接用@mobileUrl来表示Yii::getAlias('@web/static/mobile/')的意思)
* @web指的是当前项目目录下的web下, 这是框架默认的
* 而当前目录也需要配置,一般是在common/config/bootstrap.php进行配置
配置如下:Yii::setAlias('service', dirname(dirname(__DIR__)) . '/platform_service');
  查看全部
[Url::current] 获取当前路径 
现在测试本地路径(http://daxia.dc.weixin.com/mobile/hmConnections/user/verify-user) 

a: //获取当前路径 - 相对路径
$url = Url::current();
举例:/mobile/hmConnections/user/verify-user
b: //获取当前路径 - 相对路径
$url = Url::current(['id' => 1], false);
例如: /mobile/hmConnections/user/verify-user?id=1
c: //获取当前路径 - 绝对路径
$url = Url::current(['id' => 1], true);
例如: http://daxia.dc.weixin.com/mob ... d%3D1
d: //获取当前路径 - 绝对路径 传输协议-http
$url = Url::current(['id' => 1], 'http');
例如: http://daxia.dc.weixin.com/mob ... d%3D1
e: //获取当前路径 - 绝对路径 传输协议-https
$url = Url::current(['id' => 1], 'https');
例如: https://daxia.dc.weixin.com/mobile/hmConnections/user/verify-user?id=1 
 

[Url::toRoute] 获取某一地址 
现在测试本地路径(http://daxia.dc.weixin.com/mobile/hmConnections/user/verify-user) 

1://获取某地址 - 相对路径
$url = Url::toRoute('site/index');
例如: /mobile/hmConnections/site/index
2://获取某地址 - 相对路径
$url = Url::toRoute('site/index', false);
例如: /mobile/hmConnections/site/index
说明: 等价于1 因为默认是false
3://获取某地址 - 相对路径
$url = Url::toRoute(['site/index', 'id' => 1]);
例如: /mobile/hmConnections/site/index?id=1
4://获取某地址的 - 绝对路径
$url = Url::toRoute('site/index', true);
例如: http://daxia.dc.weixin.com/mob ... index
5://获取某地址的 - 绝对路径
$url = Url::toRoute('site/index', ['id' => 1]);
例如: http://daxia.dc.weixin.com/mob ... index
说明: 参数没有输出,说明,这种写法['id' => 1], 他当成了true,所以等价于4
6://获取某地址的 - 绝对路径 (传输协议-http)
$url = Url::toRoute('site/index', 'http');
例如: https://daxia.dc.weixin.com/mo ... index
说明: 等价于4
7://获取某地址的 - 绝对路径 (传输协议-https)
$url = Url::toRoute('site/index', 'https');
例如: https://daxia.dc.weixin.com/mobile/hmConnections/site/index 

[Url::to] 创建一个基于给定参数的网址
现在测试本地路径(http://daxia.dc.weixin.com/mobile/hmConnections/user/verify-user) 

1): //获某网址 - 相对路径
$url = Url::to(['site/index']);
举例:/mobile/hmConnections/site/index
说明:等价于2
2): //获取网址(带参数) - 相对路径
$url = Url::to(['site/index', 'id' => 1]);
举例:/mobile/hmConnections/site/index?id=1
说明:等价于3
3): 获取当前路径 - 相对路径
$url = Url::to();
举例:/mobile/hmConnections/user/verify-user
等价于a
4): 获取url - 相对路径
$url = Url::to('@web/image/1.jpg');
举例: /image/a.jpg
说明:它将指定到你的某一个别名目录下@web
5): 获取url - 相对路径
$url = Url::to('image/1.jpg');
举例:image/a.jpg
6): 获取url - 绝对路径(@mobileUrl 自己配置好的)
$url = Url::to('@mobileUrl/image/1.jpg', true);
举例:http://daxia.dc.weixin.com/sta ... 1.jpg
7): //获取url - 绝对路径 (传输协议-https)
$url = Url::to('@mobileUrl/image/1.jpg', 'https');
举例:https://daxia.dc.weixin.com/st ... 1.jpg
8): //获取url - 绝对路径 (传输协议-http)
$url = Url::to('@mobileUrl/image/1.jpg', 'http');
举例:http://daxia.dc.weixin.com/sta ... 1.jpg
说明:等价于 6)

** 特别说明下:@mobileUrl
$url = Url::to('@mobileUrl/city-partner/city-partner/images/1.png');
- @mobileUrl,配置如下: Yii::setAlias('@mobileUrl', Yii::getAlias('@web/static/mobile/'));
* 给Yii::getAlias('@web/static/mobile/')定义一个别名@mobileUrl(
也就是,下次我们直接用@mobileUrl来表示Yii::getAlias('@web/static/mobile/')的意思)
* @web指的是当前项目目录下的web下, 这是框架默认的
* 而当前目录也需要配置,一般是在common/config/bootstrap.php进行配置
配置如下:Yii::setAlias('service', dirname(dirname(__DIR__)) . '/platform_service');
 

PHP7 中我们应该学习会用的新特性

PHPzkbhj 发表了文章 • 0 个评论 • 1241 次浏览 • 2016-12-16 11:00 • 来自相关话题

1.标量类型声明

我们知道PHP是一种弱类型的编程语言,因此没有提供任何方法来指定输入参数和返回值的类型,PHP7突破了这种现状,增加了对标量类型(int,float,string,bool)的声明支持,增加declare(strict_types=1)指令声明是否严格类型校验,我们来看一段代码:
declare(strict_types=1)
function add(int $x, int $y) : int
{
return $x + $y;
}
echo add(1, 2); //int(3)
有效的类型有:class/interface name、self、array,、callable、bool、float、int 和 string。
 
2. NULL合并运算符

PHP7中添加了NULL合并运算符,不要小看这个“??”,有了它我们就能很方便的获取一个参数,并能在其为空的情况下提供一个默认值。如何??运算符左侧值存在并且不为NULL,则返回左侧,否则将返回其右侧值。我们还是通过下面一段代码来体验一下??运算符的强大吧。
 <?php // 获取user参数的值(如果为空,则用'nobody')
// PHP5中我们这样来实现:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
// PHP7中,使用??运算符更便捷:
$username = $_GET['user'] ?? 'nobody';
?>
 3.匿名类

顾名思义没有类名称,其声明和实例化是同时的,PHP7 支持通过 new class 来实例化一个匿名类,可以用来替代一些”用后即焚”的完整类定义。
 
echo (new class() {
public function myMethod() {
return "Hello!";
}
})->myMethod();
//Result: Hello!4. 更多Error错误可以进行异常处理

PHP7中更多的Error变为可捕获的Exception返回给开发者,如果不进行捕获则为Error,如果捕获就变为一个可在程序内处理的Exception。默认情况下,Error会直接导致程序中断,而PHP7则通过try / catch程序块捕获并且处理,让程序继续执行下去,为程序员提供更灵活的选择。

代码示例:
nonExistFunction($arg); // It will generate fatal error
 这时上面的代码会提示错误“Fatal error: Call to a member function method() on a non-object ”,并且这个致命错误会停止后面代码的继续执行。

所以如果你想继续执行代码,可以通过异常处理的方式解决:
 
try {
nonExistFunction($arg); //This method is not exists then it will be go to catch
} catch (EngineException $e ) {
echo "Exception: {$e->getMessage()}n";
}
 5.结合比较运算符 <=>

这个不多解释,我们直接看示例代码,通过代码你可以很容易了解该运算符的作用。
// PHP 7之前的写法:比较两个数的大小
function func ( $ a , $ b ) {
return ($a < $b) ? -1 : (($a > $b) ? 1 : 0)
}
// PHP新增的操作符 <=>
function func ( $ a , $ b ) {
return $a <=> $b;
}
 6.定义数组常量

过去我们在用 define() 定义常量时,数据类型只支持标量,但在 PHP7 中,支持定义数组类型的常量。
 
define('MYCONSTANT', array('a','b','c'));
 
  查看全部
1.标量类型声明

我们知道PHP是一种弱类型的编程语言,因此没有提供任何方法来指定输入参数和返回值的类型,PHP7突破了这种现状,增加了对标量类型(int,float,string,bool)的声明支持,增加declare(strict_types=1)指令声明是否严格类型校验,我们来看一段代码:
declare(strict_types=1)
function add(int $x, int $y) : int
{
return $x + $y;
}
echo add(1, 2); //int(3)

有效的类型有:class/interface name、self、array,、callable、bool、float、int 和 string。
 
2. NULL合并运算符

PHP7中添加了NULL合并运算符,不要小看这个“??”,有了它我们就能很方便的获取一个参数,并能在其为空的情况下提供一个默认值。如何??运算符左侧值存在并且不为NULL,则返回左侧,否则将返回其右侧值。我们还是通过下面一段代码来体验一下??运算符的强大吧。
 
<?php // 获取user参数的值(如果为空,则用'nobody')
// PHP5中我们这样来实现:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
// PHP7中,使用??运算符更便捷:
$username = $_GET['user'] ?? 'nobody';
?>

 3.匿名类

顾名思义没有类名称,其声明和实例化是同时的,PHP7 支持通过 new class 来实例化一个匿名类,可以用来替代一些”用后即焚”的完整类定义。
 
echo (new class() {
public function myMethod() {
return "Hello!";
}
})->myMethod();
//Result: Hello!
4. 更多Error错误可以进行异常处理

PHP7中更多的Error变为可捕获的Exception返回给开发者,如果不进行捕获则为Error,如果捕获就变为一个可在程序内处理的Exception。默认情况下,Error会直接导致程序中断,而PHP7则通过try / catch程序块捕获并且处理,让程序继续执行下去,为程序员提供更灵活的选择。

代码示例:
nonExistFunction($arg); // It will generate fatal error

 这时上面的代码会提示错误“Fatal error: Call to a member function method() on a non-object ”,并且这个致命错误会停止后面代码的继续执行。

所以如果你想继续执行代码,可以通过异常处理的方式解决:
 
try {
nonExistFunction($arg); //This method is not exists then it will be go to catch
} catch (EngineException $e ) {
echo "Exception: {$e->getMessage()}n";
}

 5.结合比较运算符 <=>

这个不多解释,我们直接看示例代码,通过代码你可以很容易了解该运算符的作用。
// PHP 7之前的写法:比较两个数的大小
function func ( $ a , $ b ) {
return ($a < $b) ? -1 : (($a > $b) ? 1 : 0)
}
// PHP新增的操作符 <=>
function func ( $ a , $ b ) {
return $a <=> $b;
}

 6.定义数组常量

过去我们在用 define() 定义常量时,数据类型只支持标量,但在 PHP7 中,支持定义数组类型的常量。
 
define('MYCONSTANT', array('a','b','c'));

 
 

设计模式:策略模式Strategy(对象行为型)

架构思想zkbhj 发表了文章 • 0 个评论 • 1312 次浏览 • 2016-12-08 10:53 • 来自相关话题

1.概述

    在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。如查找、排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…或者case等条件判断语句来进行选择。这两种实现方法我们都可以称之为硬编码,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。在这个算法类中封装了大量查找算法,该类代码将较复杂,维护较为困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。

例子1:一个菜单功能能够根据用户的“皮肤”首选项来决定是否采用水平的还是垂直的排列形式。同事可以灵活增加菜单那的显示样式。

例子2:出行旅游:我们可以有几个策略可以考虑:可以骑自行车,汽车,做火车,飞机。每个策略都可以得到相同的结果,但是它们使用了不同的资源。选择策略的依据是费用,时间,使用工具还有每种方式的方便程度 。

2.问题

如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化?


3.解决方案

策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也称为政策模式(Policy)。(Definea family of algorithms,encapsulate each one, andmake them interchangeable. Strategy lets the algorithmvary independently from clients that use it. )

策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。

4.适用性

当存在以下情况时使用Strategy模式
1)• 许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
2)• 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
3)• 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
4)• 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

5.结构





 
6.模式的组成
 
环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。

7.效果

Strategy模式有下面的一些优点:

1) 相关算法系列 Strategy类层次为Context定义了一系列的可供重用的算法或行为。 继承有助于析取出这些算法中的公共功能。
2) 提供了可以替换继承关系的办法: 继承提供了另一种支持多种算法或行为的方法。你可以直接生成一个Context类的子类,从而给它以不同的行为。但这会将行为硬行编制到 Context中,而将算法的实现与Context的实现混合起来,从而使Context难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后你得到一堆相关的类 , 它们之间的唯一差别是它们所使用的算法或行为。 将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、易于理解、易于扩展。
3) 消除了一些if else条件语句 :Strategy模式提供了用条件语句选择所需的行为以外的另一种选择。当不同的行为堆砌在一个类中时 ,很难避免使用条件语句来选择合适的行为。将行为封装在一个个独立的Strategy类中消除了这些条件语句。含有许多条件语句的代码通常意味着需要使用Strategy模式。
4) 实现的选择 Strategy模式可以提供相同行为的不同实现。客户可以根据不同时间 /空间权衡取舍要求从不同策略中进行选择。

Strategy模式缺点:

1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类:  本模式有一个潜在的缺点,就是一个客户要选择一个合适的Strategy就必须知道这些Strategy到底有何不同。此时可能不得不向客户暴露具体的实现问题。因此仅当这些不同行为变体与客户相关的行为时 , 才需要使用Strategy模式。
2 ) Strategy和Context之间的通信开销 :无论各个ConcreteStrategy实现的算法是简单还是复杂, 它们都共享Strategy定义的接口。因此很可能某些 ConcreteStrategy不会都用到所有通过这个接口传递给它们的信息;简单的 ConcreteStrategy可能不使用其中的任何信息!这就意味着有时Context会创建和初始化一些永远不会用到的参数。如果存在这样问题 , 那么将需要在Strategy和Context之间更进行紧密的耦合。
3 )策略模式将造成产生很多策略类:可以通过使用享元模式在一定程度上减少对象的数量。 增加了对象的数目 Strategy增加了一个应用中的对象的数目。有时你可以将 Strategy实现为可供各Context共享的无状态的对象来减少这一开销。任何其余的状态都由 Context维护。Context在每一次对Strategy对象的请求中都将这个状态传递过去。共享的 Strategy不应在各次调用之间维护状态。

8.实现

1)出行旅游:
 
uml:





 
代码实现:
<?php
/**
* 策略模式
* 定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化
*
*/


/**
* 出行旅游
*
*
*/
interface TravelStrategy{
public function travelAlgorithm();
}


/**
* 具体策略类(ConcreteStrategy)1:乘坐飞机
*/
class AirPlanelStrategy implements TravelStrategy {
public function travelAlgorithm(){
echo "travel by AirPlain", "<BR>\r\n";
}
}


/**
* 具体策略类(ConcreteStrategy)2:乘坐火车
*/
class TrainStrategy implements TravelStrategy {
public function travelAlgorithm(){
echo "travel by Train", "<BR>\r\n";
}
}

/**
* 具体策略类(ConcreteStrategy)3:骑自行车
*/
class BicycleStrategy implements TravelStrategy {
public function travelAlgorithm(){
echo "travel by Bicycle", "<BR>\r\n";
}
}



/**
*
* 环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
* 算法解决类,以提供客户选择使用何种解决方案:
*/
class PersonContext{
private $_strategy = null;

public function __construct(TravelStrategy $travel){
$this->_strategy = $travel;
}
/**
* 旅行
*/
public function setTravelStrategy(TravelStrategy $travel){
$this->_strategy = $travel;
}
/**
* 旅行
*/
public function travel(){
return $this->_strategy ->travelAlgorithm();
}
}

// 乘坐火车旅行
$person = new PersonContext(new TrainStrategy());
$person->travel();

// 改骑自行车
$person->setTravelStrategy(new BicycleStrategy());
$person->travel();

?> 2)排序策略:某系统提供了一个用于对数组数据进行操作的类,该类封装了对数组的常见操作,

如查找数组元素、对数组元素进行排序等。现以排序操作为例,使用策略模式设计该数组操作类,

使得客户端可以动态地更换排序算法,可以根据需要选择冒泡排序或选择排序或插入排序,

也能够灵活地增加新的排序算法。
 
9.与其他相关模式

1)状态模式

策略模式和其它许多设计模式比较起来是非常类似的。策略模式和状态模式最大的区别就是策略模式只是的条件选择只执行一次,而状态模式是随着实例参数(对象实例的状态)的改变不停地更改执行模式。换句话说,策略模式只是在

对象初始化的时候更改执行模式,而状态模式是根据对象实例的周期时间而动态地改变对象实例的执行模式。

•可以通过环境类状态的个数来决定是使用策略模式还是状态模式。
•策略模式的环境类自己选择一个具体策略类,具体策略类无须关心环境类;而状态模式的环境类由于外在因素需要放进一个具体状态中,
以便通过其方法实现状态的切换,因此环境类和状态类之间存在一种双向的关联关系。
•使用策略模式时,客户端需要知道所选的具体策略是哪一个,而使用状态模式时,客户端无须关心具体状态,环境类的状态会根据用户的操作自动转换。
•如果系统中某个类的对象存在多种状态,不同状态下行为有差异,而且这些状态之间可以发生转换时使用状态模式;
如果系统中某个类的某一行为存在多种实现方式,而且这些实现方式可以互换时使用策略模式。

2)简单工厂的区别:点击打开链接

工厂模式是创建型模式 ,它关注对象创建,提供创建对象的接口. 让对象的创建与具体的使用客户无关。
策略模式是对象行为型模式 ,它关注行为和算法的封装 。它定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。使得算法可独立于使用它的客户而变化

用我们上面提到旅行的例子:
我们去旅行。策略模式的做法:有几种方案供你选择旅行,选择火车好呢还是骑自行车,完全有客户自行决定去构建旅行方案(比如你自己需要去买火车票,或者机票)。而工厂模式是你决定哪种旅行方案后,不用关注这旅行方案怎么给你创建,也就是说你告诉我方案的名称就可以了,然后由工厂代替你去构建具体方案(工厂代替你去买火车票)。

上面的例子里面client代码:
$person = new PersonContext(new TrainStrategy());
$person->travel();
我们看到客户需要自己去创建具体旅行(new TrainStrategy())实例。传递的是具体实例。
而工厂模式你只要告诉哪种旅行就可以了,不是传递一个具体实例,而是一个标识(旅行方案标识)。

10.总结与分析

1)策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
2)在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色。2)
3)策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。

原文地址:http://blog.csdn.net/hguisu/ar ... 8249/ 查看全部
1.概述

    在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。如查找、排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…或者case等条件判断语句来进行选择。这两种实现方法我们都可以称之为硬编码,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。在这个算法类中封装了大量查找算法,该类代码将较复杂,维护较为困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。

例子1:一个菜单功能能够根据用户的“皮肤”首选项来决定是否采用水平的还是垂直的排列形式。同事可以灵活增加菜单那的显示样式。

例子2:出行旅游:我们可以有几个策略可以考虑:可以骑自行车,汽车,做火车,飞机。每个策略都可以得到相同的结果,但是它们使用了不同的资源。选择策略的依据是费用,时间,使用工具还有每种方式的方便程度 。

2.问题

如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化?


3.解决方案

策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也称为政策模式(Policy)。(Definea family of algorithms,encapsulate each one, andmake them interchangeable. Strategy lets the algorithmvary independently from clients that use it. )

策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。

4.适用性

当存在以下情况时使用Strategy模式
1)• 许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
2)• 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
3)• 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
4)• 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

5.结构

1336732187_4598.jpg

 
6.模式的组成
 
  • 环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
  • 抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
  • 具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。


7.效果

Strategy模式有下面的一些优点:

1) 相关算法系列 Strategy类层次为Context定义了一系列的可供重用的算法或行为。 继承有助于析取出这些算法中的公共功能。
2) 提供了可以替换继承关系的办法: 继承提供了另一种支持多种算法或行为的方法。你可以直接生成一个Context类的子类,从而给它以不同的行为。但这会将行为硬行编制到 Context中,而将算法的实现与Context的实现混合起来,从而使Context难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后你得到一堆相关的类 , 它们之间的唯一差别是它们所使用的算法或行为。 将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、易于理解、易于扩展。
3) 消除了一些if else条件语句 :Strategy模式提供了用条件语句选择所需的行为以外的另一种选择。当不同的行为堆砌在一个类中时 ,很难避免使用条件语句来选择合适的行为。将行为封装在一个个独立的Strategy类中消除了这些条件语句。含有许多条件语句的代码通常意味着需要使用Strategy模式。
4) 实现的选择 Strategy模式可以提供相同行为的不同实现。客户可以根据不同时间 /空间权衡取舍要求从不同策略中进行选择。

Strategy模式缺点:

1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类:  本模式有一个潜在的缺点,就是一个客户要选择一个合适的Strategy就必须知道这些Strategy到底有何不同。此时可能不得不向客户暴露具体的实现问题。因此仅当这些不同行为变体与客户相关的行为时 , 才需要使用Strategy模式。
2 ) Strategy和Context之间的通信开销 :无论各个ConcreteStrategy实现的算法是简单还是复杂, 它们都共享Strategy定义的接口。因此很可能某些 ConcreteStrategy不会都用到所有通过这个接口传递给它们的信息;简单的 ConcreteStrategy可能不使用其中的任何信息!这就意味着有时Context会创建和初始化一些永远不会用到的参数。如果存在这样问题 , 那么将需要在Strategy和Context之间更进行紧密的耦合。
3 )策略模式将造成产生很多策略类:可以通过使用享元模式在一定程度上减少对象的数量。 增加了对象的数目 Strategy增加了一个应用中的对象的数目。有时你可以将 Strategy实现为可供各Context共享的无状态的对象来减少这一开销。任何其余的状态都由 Context维护。Context在每一次对Strategy对象的请求中都将这个状态传递过去。共享的 Strategy不应在各次调用之间维护状态。

8.实现

1)出行旅游:
 
uml:

1336733743_7225.jpg

 
代码实现:
<?php  
/**
* 策略模式
* 定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化
*
*/


/**
* 出行旅游
*
*
*/
interface TravelStrategy{
public function travelAlgorithm();
}


/**
* 具体策略类(ConcreteStrategy)1:乘坐飞机
*/
class AirPlanelStrategy implements TravelStrategy {
public function travelAlgorithm(){
echo "travel by AirPlain", "<BR>\r\n";
}
}


/**
* 具体策略类(ConcreteStrategy)2:乘坐火车
*/
class TrainStrategy implements TravelStrategy {
public function travelAlgorithm(){
echo "travel by Train", "<BR>\r\n";
}
}

/**
* 具体策略类(ConcreteStrategy)3:骑自行车
*/
class BicycleStrategy implements TravelStrategy {
public function travelAlgorithm(){
echo "travel by Bicycle", "<BR>\r\n";
}
}



/**
*
* 环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
* 算法解决类,以提供客户选择使用何种解决方案:
*/
class PersonContext{
private $_strategy = null;

public function __construct(TravelStrategy $travel){
$this->_strategy = $travel;
}
/**
* 旅行
*/
public function setTravelStrategy(TravelStrategy $travel){
$this->_strategy = $travel;
}
/**
* 旅行
*/
public function travel(){
return $this->_strategy ->travelAlgorithm();
}
}

// 乘坐火车旅行
$person = new PersonContext(new TrainStrategy());
$person->travel();

// 改骑自行车
$person->setTravelStrategy(new BicycleStrategy());
$person->travel();

?>
2)排序策略:某系统提供了一个用于对数组数据进行操作的类,该类封装了对数组的常见操作,

如查找数组元素、对数组元素进行排序等。现以排序操作为例,使用策略模式设计该数组操作类,

使得客户端可以动态地更换排序算法,可以根据需要选择冒泡排序或选择排序或插入排序,

也能够灵活地增加新的排序算法。
 
9.与其他相关模式

1)状态模式

策略模式和其它许多设计模式比较起来是非常类似的。策略模式和状态模式最大的区别就是策略模式只是的条件选择只执行一次,而状态模式是随着实例参数(对象实例的状态)的改变不停地更改执行模式。换句话说,策略模式只是在

对象初始化的时候更改执行模式,而状态模式是根据对象实例的周期时间而动态地改变对象实例的执行模式。

•可以通过环境类状态的个数来决定是使用策略模式还是状态模式。
•策略模式的环境类自己选择一个具体策略类,具体策略类无须关心环境类;而状态模式的环境类由于外在因素需要放进一个具体状态中,
以便通过其方法实现状态的切换,因此环境类和状态类之间存在一种双向的关联关系。
•使用策略模式时,客户端需要知道所选的具体策略是哪一个,而使用状态模式时,客户端无须关心具体状态,环境类的状态会根据用户的操作自动转换。
•如果系统中某个类的对象存在多种状态,不同状态下行为有差异,而且这些状态之间可以发生转换时使用状态模式;
如果系统中某个类的某一行为存在多种实现方式,而且这些实现方式可以互换时使用策略模式。

2)简单工厂的区别:点击打开链接

工厂模式是创建型模式 ,它关注对象创建,提供创建对象的接口. 让对象的创建与具体的使用客户无关。
策略模式是对象行为型模式 ,它关注行为和算法的封装 。它定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。使得算法可独立于使用它的客户而变化

用我们上面提到旅行的例子:
我们去旅行。策略模式的做法:有几种方案供你选择旅行,选择火车好呢还是骑自行车,完全有客户自行决定去构建旅行方案(比如你自己需要去买火车票,或者机票)。而工厂模式是你决定哪种旅行方案后,不用关注这旅行方案怎么给你创建,也就是说你告诉我方案的名称就可以了,然后由工厂代替你去构建具体方案(工厂代替你去买火车票)。

上面的例子里面client代码:
$person = new PersonContext(new TrainStrategy());
$person->travel();
我们看到客户需要自己去创建具体旅行(new TrainStrategy())实例。传递的是具体实例。
而工厂模式你只要告诉哪种旅行就可以了,不是传递一个具体实例,而是一个标识(旅行方案标识)。

10.总结与分析

1)策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
2)在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色。2)
3)策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。

原文地址:http://blog.csdn.net/hguisu/ar ... 8249/

电影《你的名字。》精彩影评摘录

影视zkbhj 发表了文章 • 0 个评论 • 1883 次浏览 • 2016-12-06 14:21 • 来自相关话题

 《人世间所有的相遇都是久别重逢》

事实上,新海诚一直都不是我个人所喜欢的动画电影导演。他的动画总是充满绚烂多彩的画面,给人一种非常梦幻而不真实的感觉,唯美而忧伤,莫名其妙的哀愁。不过画面的美丽也算得上是新海诚的重要优势之一,但与之相对应的则是其在故事脚本上的弱势一直为人所诟病。

对于一部分影迷,包括我自己而言,一部电影的故事的重要程度要远超于其画面的美丽或者其他一切艺术手法。而新海诚导演的几部动画电影都有着同样的问题,过分重视画面的质感,而忽视了电影的故事性。比如《秒速5厘米》中漫天随风落下的樱花,《言叶之庭》中细腻真实的雨水。美则美矣,但故事总是让人接受无力。

不过这一问题被其最新作品《你的名字》所改变了。这部电影不仅仅有着新海诚标志性的美不胜收的画面,而且还在故事脚本上有了质的突破。画面与故事的尽善尽美,一起成就了这部电影。最终电影在日本上映两天拿下超过7亿日元的票房,被新海诚自称为他的最高杰作。

据新海诚自己介绍说,电影的故事来源于一首著名的日本和歌,歌词大意为:“梦里相逢人不见,若知是梦何须醒。纵然梦里常幽会,怎比真如见一回。”新海诚把这个梦中相见的故事更进一步地改编成为了一个两个人在梦中交换身体生活的故事,并加上了一个千年一遇的彗星重返地球的“末日背景”,这让整个故事变得有趣而吸引人了。

女主角三叶是一个生活在深山之中的乡村女孩,母亲早逝,父亲忙于竞选,自己与外婆和妹妹一起生活。小镇生活平淡无聊,三叶早已厌倦这里的一切,希望去往大城市东京生活;而男主角泷则是东京的一名高中生,与父亲生活,经常去餐厅打工,同样平淡而无聊的生活。

一切都从他们的梦中开始改变。

梦中的三叶进入了泷的身体,过上了她一直想要的东京生活;而梦中的泷则进入三叶的身体,变成了一个帅气的女生,勇敢地面对所有流言蜚语。就这样,他们不定期地在梦中交换身体,并给对方留下当天的日记,用文字互相交流。

电影中的这一部分非常有趣,同一个身体却是两个不同的人格,三叶变得时而内向胆怯时而勇敢帅气,泷也变得时而神经大条时而温柔体贴,这对他们各自的生活都产生了非常有趣的影响,更是让他们的朋友感到困惑。

在新海诚以往的电影中,男女主角总是沉浸在自己的世界中,与世隔绝般地孤独、思考、独自生活。而在这部《你的名字》中,男女主角终于一反常态,进入了像所有正常人一样的生活,他们也被赋予了朋友、家人、同事这样的社会关系网,让这一切都变得更广阔和大众,不再是孤芳自赏般的个人情绪的展现。

少年与少女在时空之间不断地穿越,互相交流也互相影响,但他们始终没能相遇。
 
这一设定已经足够吸引人了,但新海诚在此基础上还加入了彗星来临的“末日情绪”,更是让人大吃一惊。虽然电影的前半段,彗星的来临一直被作为是一种美丽的自然天象来展示的,直到最后才突然意识到彗星即将毁灭小镇的事实,这让整部电影的故事性更上一层,变得更加精彩了。

随着彗星的接近,故事不断发展,少年泷突然意识到好像在某一次之后再也没有类似的梦境了。他开始怀疑一切,怀疑这梦中的故事究竟是梦还是事实,梦中的那个少女到底存不存在。为此,他踏上了寻找那个梦中小镇的道路。

然而他所发现的事实不仅让他大吃一惊,更是让观众也同样惊讶。原来梦中的故事不仅仅是一个空间的穿越,还是一个时间的穿越。少女三叶是三年前的少女,而少年泷是现在的少年,他们共同做的这个梦的终极意义是试图拯救整个小镇的居民。

故事的最后,他们共同历经千辛万苦终于拯救了小镇。少女三叶终于在灾难之中活了下来,来到东京生活;少年泷也同样一直在东京继续生活。但是他们却互相遗忘了梦中的故事,忘记了那个不能忘,也不想忘的名字,只是隐隐记得一直在追寻的那个人。

要是以新海诚以往的调性,或许故事会就此结束,留下淡淡忧伤的结局,甚至会更催泪的让男女主角在人海中插肩而过却无法相识。但在这部电影中,新海诚竟然给出了一个Happy Ending,反而更加催泪更加动人。

冬去春来,地铁上的偶然一瞥,惊人的似曾相似的感觉,让他们互相寻找对方。可是见面之后,却又没有勇气说话,强忍着冲动,默默低头插肩而过,直教所有观众为他们着急。

直到少年泷一低头,一咬牙,大喊一声:请问,我在哪里见过你吗?

少女泪如雨下,微笑着说:我也是。

感动在这一瞬间达到极致,这种纯粹美好的爱情让人无比羡慕,中二病和少女心在这一刻都值得原谅,真是抵挡不住的美好。

人世间所有的相遇都是久别重复,即使没有真正的遇见过彼此,但或许是在梦中。毕竟梦这种东西,醒来之后就会消失的。

享受梦境吧,或者珍惜每一个相遇的人,或者告诉我你的名字吧。

原文地址:https://movie.douban.com/review/8086457/ 查看全部

p2395733377.jpg

 《人世间所有的相遇都是久别重逢》

事实上,新海诚一直都不是我个人所喜欢的动画电影导演。他的动画总是充满绚烂多彩的画面,给人一种非常梦幻而不真实的感觉,唯美而忧伤,莫名其妙的哀愁。不过画面的美丽也算得上是新海诚的重要优势之一,但与之相对应的则是其在故事脚本上的弱势一直为人所诟病。

对于一部分影迷,包括我自己而言,一部电影的故事的重要程度要远超于其画面的美丽或者其他一切艺术手法。而新海诚导演的几部动画电影都有着同样的问题,过分重视画面的质感,而忽视了电影的故事性。比如《秒速5厘米》中漫天随风落下的樱花,《言叶之庭》中细腻真实的雨水。美则美矣,但故事总是让人接受无力。

不过这一问题被其最新作品《你的名字》所改变了。这部电影不仅仅有着新海诚标志性的美不胜收的画面,而且还在故事脚本上有了质的突破。画面与故事的尽善尽美,一起成就了这部电影。最终电影在日本上映两天拿下超过7亿日元的票房,被新海诚自称为他的最高杰作。

据新海诚自己介绍说,电影的故事来源于一首著名的日本和歌,歌词大意为:“梦里相逢人不见,若知是梦何须醒。纵然梦里常幽会,怎比真如见一回。”新海诚把这个梦中相见的故事更进一步地改编成为了一个两个人在梦中交换身体生活的故事,并加上了一个千年一遇的彗星重返地球的“末日背景”,这让整个故事变得有趣而吸引人了。

女主角三叶是一个生活在深山之中的乡村女孩,母亲早逝,父亲忙于竞选,自己与外婆和妹妹一起生活。小镇生活平淡无聊,三叶早已厌倦这里的一切,希望去往大城市东京生活;而男主角泷则是东京的一名高中生,与父亲生活,经常去餐厅打工,同样平淡而无聊的生活。

一切都从他们的梦中开始改变。

梦中的三叶进入了泷的身体,过上了她一直想要的东京生活;而梦中的泷则进入三叶的身体,变成了一个帅气的女生,勇敢地面对所有流言蜚语。就这样,他们不定期地在梦中交换身体,并给对方留下当天的日记,用文字互相交流。

电影中的这一部分非常有趣,同一个身体却是两个不同的人格,三叶变得时而内向胆怯时而勇敢帅气,泷也变得时而神经大条时而温柔体贴,这对他们各自的生活都产生了非常有趣的影响,更是让他们的朋友感到困惑。

在新海诚以往的电影中,男女主角总是沉浸在自己的世界中,与世隔绝般地孤独、思考、独自生活。而在这部《你的名字》中,男女主角终于一反常态,进入了像所有正常人一样的生活,他们也被赋予了朋友、家人、同事这样的社会关系网,让这一切都变得更广阔和大众,不再是孤芳自赏般的个人情绪的展现。

少年与少女在时空之间不断地穿越,互相交流也互相影响,但他们始终没能相遇。
 
这一设定已经足够吸引人了,但新海诚在此基础上还加入了彗星来临的“末日情绪”,更是让人大吃一惊。虽然电影的前半段,彗星的来临一直被作为是一种美丽的自然天象来展示的,直到最后才突然意识到彗星即将毁灭小镇的事实,这让整部电影的故事性更上一层,变得更加精彩了。

随着彗星的接近,故事不断发展,少年泷突然意识到好像在某一次之后再也没有类似的梦境了。他开始怀疑一切,怀疑这梦中的故事究竟是梦还是事实,梦中的那个少女到底存不存在。为此,他踏上了寻找那个梦中小镇的道路。

然而他所发现的事实不仅让他大吃一惊,更是让观众也同样惊讶。原来梦中的故事不仅仅是一个空间的穿越,还是一个时间的穿越。少女三叶是三年前的少女,而少年泷是现在的少年,他们共同做的这个梦的终极意义是试图拯救整个小镇的居民。

故事的最后,他们共同历经千辛万苦终于拯救了小镇。少女三叶终于在灾难之中活了下来,来到东京生活;少年泷也同样一直在东京继续生活。但是他们却互相遗忘了梦中的故事,忘记了那个不能忘,也不想忘的名字,只是隐隐记得一直在追寻的那个人。

要是以新海诚以往的调性,或许故事会就此结束,留下淡淡忧伤的结局,甚至会更催泪的让男女主角在人海中插肩而过却无法相识。但在这部电影中,新海诚竟然给出了一个Happy Ending,反而更加催泪更加动人。

冬去春来,地铁上的偶然一瞥,惊人的似曾相似的感觉,让他们互相寻找对方。可是见面之后,却又没有勇气说话,强忍着冲动,默默低头插肩而过,直教所有观众为他们着急。

直到少年泷一低头,一咬牙,大喊一声:请问,我在哪里见过你吗?

少女泪如雨下,微笑着说:我也是。

感动在这一瞬间达到极致,这种纯粹美好的爱情让人无比羡慕,中二病和少女心在这一刻都值得原谅,真是抵挡不住的美好。

人世间所有的相遇都是久别重复,即使没有真正的遇见过彼此,但或许是在梦中。毕竟梦这种东西,醒来之后就会消失的。

享受梦境吧,或者珍惜每一个相遇的人,或者告诉我你的名字吧。

原文地址:https://movie.douban.com/review/8086457/

docker的常用命令

服务器zkbhj 发表了文章 • 0 个评论 • 1390 次浏览 • 2016-12-06 11:35 • 来自相关话题

1、查看当前的Docker虚拟机的状态:docker-machine ls
 
2、创建一个Docker虚拟机:docker-machine create --driver=virtualbox default
3、获得虚拟机的环境变量:docker-machine env default
4、把当前的PowerShell和虚拟机里面的Docker Linux建立连接,可以在PowerShell中使用docker命令:docker-machine env default | Invoke-Expression
5、查看虚拟机的ip地址:docker-machine ip6、查看当前有哪些镜像:docker images7、当前有哪些容器:docker ps –a8、查看docker所有容器和镜像的数量、docker使用的执行驱动和存储驱动,以及docker的基本配置:docker info9、创建容器:docker run -i -t ubuntu /bin/bash




-i标志保证容器中STDIN是开启的 -t告诉docker为创建的容器分配一个伪tty终端,进而该容器才能提供一个交互式的shell Ubuntu 是一个基础镜像,指定该容器基于那哥基础镜像为基础 仅启动了一个容器,未向容器内添加任何东西/bin/bash 命令告诉docker在新容器中要运行什么命令
 
10、给容器命名:--namedocker run --name mydockername -i -t ubuntu /bin/bash



 11、容器的启动、重新启动和创建(不运行):docker start mydockername
docker restart mydockername
docker create mydockername
12、附着到正在运行的容器上:docker attach mydockername/mydockerid13、创建守护式容器:-ddocker run --name mydockername -d centos /bin/sh -c "while true;do echo hello zhengkai;sleep 1;done"14、获取守护式容器的日志:docker logs (-f) mydockername15、查看容器内的进程docker top mydockername16、查看一个活多个容器的统计信息docker status mydockername1 mydockername2 mydockername317、在docker容器内部运行进程:docker exec -d mydockername touch /etc/new_config_file18、停止容器命令docker stop mydockername
docker kill mydockername19、自动重启容器:docker run --restart=always --name mydockername -d centos /bin/sh -c "while true;do echo zhengkai;sleep 1;done"always:无论容器推出代码是什么,都重启容器
on-failure:当容器的推出代码为非0时,退出容器,可以指定重启次数参数。 
20、深入容器:docker inspect mydockername
docker inspet --format='{{ .State.Running }}' mydockername21、删除容器:docker rm mydockername
docker rm mydockername 'docker ps -a -q'22、列出docker镜像:
docker images23、单独拉取仓库中的镜像:
docker pull centos:11.01    下载完成后可以使用下面的命令查看:
docker images centos 查看全部
1、查看当前的Docker虚拟机的状态:
docker-machine ls

 
2、创建一个Docker虚拟机:
docker-machine create --driver=virtualbox default

3、获得虚拟机的环境变量:
docker-machine env default

4、把当前的PowerShell和虚拟机里面的Docker Linux建立连接,可以在PowerShell中使用docker命令:
docker-machine env default | Invoke-Expression

5、查看虚拟机的ip地址:
docker-machine ip
6、查看当前有哪些镜像:
docker images
7、当前有哪些容器:
docker ps –a
8、查看docker所有容器和镜像的数量、docker使用的执行驱动和存储驱动,以及docker的基本配置:
docker info
9、创建容器:
docker run -i -t ubuntu /bin/bash




  • -i标志保证容器中STDIN是开启的 
  • -t告诉docker为创建的容器分配一个伪tty终端,进而该容器才能提供一个交互式的shell 
  • Ubuntu 是一个基础镜像,指定该容器基于那哥基础镜像为基础 
  • 仅启动了一个容器,未向容器内添加任何东西
  • /bin/bash 命令告诉docker在新容器中要运行什么命令

 
10、给容器命名:--name
docker run --name mydockername -i -t ubuntu /bin/bash



 11、容器的启动、重新启动和创建(不运行):
docker start mydockername
docker restart mydockername
docker create mydockername

12、附着到正在运行的容器上:
docker attach mydockername/mydockerid
13、创建守护式容器:-d
docker run --name mydockername -d centos /bin/sh -c "while true;do echo hello zhengkai;sleep 1;done"
14、获取守护式容器的日志:
docker logs (-f) mydockername
15、查看容器内的进程
docker top mydockername
16、查看一个活多个容器的统计信息
docker status mydockername1 mydockername2 mydockername3
17、在docker容器内部运行进程:
docker exec -d mydockername touch /etc/new_config_file
18、停止容器命令
docker stop mydockername
docker kill mydockername
19、自动重启容器:
docker run --restart=always --name mydockername -d centos /bin/sh -c "while true;do echo zhengkai;sleep 1;done"
always:无论容器推出代码是什么,都重启容器
on-failure:当容器的推出代码为非0时,退出容器,可以指定重启次数参数。 
20、深入容器:
docker inspect mydockername
docker inspet --format='{{ .State.Running }}' mydockername
21、删除容器:
docker rm mydockername
docker rm mydockername 'docker ps -a -q'
22、列出docker镜像:
docker images
23、单独拉取仓库中的镜像:
docker pull centos:11.01
    下载完成后可以使用下面的命令查看:
docker images centos

PHP工程师的任职要求和岗位职责

随手记zkbhj 发表了文章 • 0 个评论 • 1566 次浏览 • 2016-12-05 18:28 • 来自相关话题

岗位职责:
1、根据产品、运营和推广需求,进行客户端server或者web端server的开发
2、负责开企业平台的开发维护
3、负责产品架构高可用性、高可扩展性方向的优化调整 ,新技术调研引入
4、负责对现有系统的不足进行分析,找到目前系统的瓶颈,改进系统算法,提高系统性能

任职要求:
1、熟悉PHP语言的开发工作,熟练掌握LAMP开发,熟悉PHP框架,如Yii
2、具备Web或客户端sever的应用系统开发经验
3、熟悉MySQL、Mongodb、Redis等数据库设计及优化
4、熟悉Linux/Unix,具有系统分析能力
5、具有良好的学习能力、时间和流程意识、沟通能力、团队合作、坦诚直接
6、3年以上PHP开发经验,大专以上学历 查看全部
岗位职责:
1、根据产品、运营和推广需求,进行客户端server或者web端server的开发
2、负责开企业平台的开发维护
3、负责产品架构高可用性、高可扩展性方向的优化调整 ,新技术调研引入
4、负责对现有系统的不足进行分析,找到目前系统的瓶颈,改进系统算法,提高系统性能

任职要求:
1、熟悉PHP语言的开发工作,熟练掌握LAMP开发,熟悉PHP框架,如Yii
2、具备Web或客户端sever的应用系统开发经验
3、熟悉MySQL、Mongodb、Redis等数据库设计及优化
4、熟悉Linux/Unix,具有系统分析能力
5、具有良好的学习能力、时间和流程意识、沟通能力、团队合作、坦诚直接
6、3年以上PHP开发经验,大专以上学历

PHP函数:strpos()

PHPzkbhj 发表了文章 • 0 个评论 • 1189 次浏览 • 2016-12-05 15:47 • 来自相关话题

strpos() 函数查找字符串在另一字符串中第一次出现的位置。
strpos(string,find,start)参数 描述
string 必需。规定要搜索的字符串。
find 必需。规定要查找的字符串。
start 可选。规定在何处开始搜索。

相关函数:
stripos() - 查找字符串在另一字符串中第一次出现的位置(不区分大小写)
strripos() - 查找字符串在另一字符串中最后一次出现的位置(不区分大小写)
strrpos() - 查找字符串在另一字符串中最后一次出现的位置(区分大小写) 查看全部
strpos() 函数查找字符串在另一字符串中第一次出现的位置。
strpos(string,find,start)
参数 描述
string 必需。规定要搜索的字符串。
find 必需。规定要查找的字符串。
start 可选。规定在何处开始搜索。

相关函数:
stripos() - 查找字符串在另一字符串中第一次出现的位置(不区分大小写)
strripos() - 查找字符串在另一字符串中最后一次出现的位置(不区分大小写)
strrpos() - 查找字符串在另一字符串中最后一次出现的位置(区分大小写)

PHP函数:字符串大小写转换函数

PHPzkbhj 发表了文章 • 0 个评论 • 1292 次浏览 • 2016-12-05 15:04 • 来自相关话题

1、将字符串转换成小写
strtolower函数: 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式放回这个字符串。

例子:<?php
$str = "I want To FLY";
$str = strtolower($str);
echo $str;
?>
输出:
i want to fly2、将字符转成大写
strtoupper函数:该函数的作用同strtolower函数相反,是将传入的字符参数的字符全部转换成大写,并以大写的形式返回这个字符串。
用法同strtolower()一样。
 
3、将字符串首字符转换成大写
ucfirst函数: 该函数的作用是将字符串的第一个字符改成大写,该函数返回首字符大写的字符串。
用法同strtolower()函数类似。

4、将字符串每个单词的首字符转换成大写
ucwords: 该函数将传入的字符串的每个单词的首字符变成大写。如"hello world",经过该函数处理后,将返回"Hello Word"。
用法同strtolower()类似。 查看全部
1、将字符串转换成小写
strtolower函数: 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式放回这个字符串。

例子:
<?php
$str = "I want To FLY";
$str = strtolower($str);
echo $str;
?>
输出:
i want to fly
2、将字符转成大写
strtoupper函数:该函数的作用同strtolower函数相反,是将传入的字符参数的字符全部转换成大写,并以大写的形式返回这个字符串。
用法同strtolower()一样。
 
3、将字符串首字符转换成大写
ucfirst函数: 该函数的作用是将字符串的第一个字符改成大写,该函数返回首字符大写的字符串。
用法同strtolower()函数类似。

4、将字符串每个单词的首字符转换成大写
ucwords: 该函数将传入的字符串的每个单词的首字符变成大写。如"hello world",经过该函数处理后,将返回"Hello Word"。
用法同strtolower()类似。