一切福田,不離方寸,從心而覓,感無不通。

Category Archives: PHP

现代 PHP 新特性系列(二) —— 善用接口

接口不是现代PHP的新特性,但是非常重要,学会使用接口,可以极大提升我们的编程能力,所以在日常开发中应该尽可能多地使用接口。 接口是两个PHP对象之间的契约(Contract),Laravel底层就直接将接口放在Contracts目录中: 接口将我们的代码和依赖解耦了,而且允许我们的代码依赖任何实现了预期接口的第三方代码,我们不管第三方代码是如何实现接口的,只关心第三方代码是否实现了指定的接口。 如果我们编写的代码需要处理指定类的对象,那么代码的功用就完全被限定了,因为始终只能使用那个类的对象,可是,如果编写的代码处理的是接口,那么代码立即就能知道如何处理实现这一接口的任何对象,我们不关心接口是如何实现的,只关心是否实现了指定的接口。 我们以上述Laravel底层提供的CacheStore(Store接口)为例,这个接口的作用是封装缓存存储器的通用方法,包括get、put、flush等:

这么做的好处是可以分开定义具体的缓存实现方式,比如Laravel支持数组(Array)、数据库(Database)、文件(File)、Apc、Memcache、Redis等缓存存储器,方便我们在代码中使用相应的方式对数据进行缓存。我们以Memcached驱动为例,其对应实现类是MemcachedStore:

可以看到我们在构造函数中传入了Memcached实例,然后在此实例基础上具体实现接口所定义的方法,其他的实现类也是类似,这样通过Store接口,我们就将缓存代码和具体依赖解耦,方便后续扩展以及供其他人使用。比如这里我们定义一个CacheStore类:

然后我们可以在配置文件中配置使用的默认缓存驱动,比如Memcached,然后在代码中调用时这样使用:

注:这里只是做简单演示,不要真的这么去使用Laravel提供的缓存功能,实际上Laravel底层对缓存处理要比我这里的演示代码优雅的多。 总之,使用接口编写的代码更灵活,能委托别人实现细节,使用接口后会有越来越多的人使用你的代码,因为他们只需要知道如何实现接口,就可以无缝地使用你的代码。实际上,我们在使用服务提供者和依赖注入时也是以这种面向接口编程为基础进行了更复杂的扩展而已。   from:http://laravelacademy.org/post/4246.html

龙生   13 Aug 2017
View Details

现代 PHP 新特性系列(一) —— 命名空间

1、什么是命名空间 如果你只需要知道现代PHP特性中的一个,那就应该是命名空间。命名空间在PHP5.3.0中引入,其作用是按照一种虚拟的层次结构组织PHP代码,这种层次结构类似操作系统中文件系统的目录结构。命名空间是现代PHP组件生态的基础,现代的PHP组件框架代码都是放在各自全局唯一的厂商命名空间中,以免和其他厂商使用的常见类名冲突。 下面我来看看真实的PHP组件是如何使用命名空间的。Laravel框架中的Http组件用于管理HTTP请求和响应,这个组件用到了常见的类名,例如Request、Response,很多其他PHP组件也用到了这样的类名,既然其他PHP代码也用到了相同的类名,那怎么使用这个组件呢?其实我们可以放心使用,因为这个组件的代码放在了唯一的厂商命名空间Illuminate中。打开这个组件在GitHub中的仓库(https://github.com/laravel/framework/blob/master/src/Illuminate/Http/Response.php),找到Response.php文件: 第3行代码如下:

这一行是PHP命名空间声明语句,声明命名空间的代码始终应该放在<?php标签后的第一行。通过这个命名空间的声明语句我们可以看到Response位于厂商命名空间Illuminate中(最顶层命名空间),我们还看到Response类在子命名空间Http中,你可以看下和Response.php文件在同一层级的其他文件,会发现它们都使用相同的命名空间声明语句。 命名空间的作用是封装和组织相关的PHP类,就像在文件系统中把相关的文件放在同一个目录中一样。PHP命名空间和操作系统的物理文件系统不同,这是一个虚拟概念,没必要和文件系统中的目录结构完全相同,虽然如此,但是大多数PHP组件为了兼容广泛使用的PSR-4自动加载标准,会把命名空间放到对应文件系统的子目录中。 2、为什么使用命名空间 前面已经提到过,我们的代码可能和其他开发者的代码使用相同的类名、接口名、函数或常量名,如果不使用命名空间,名称会起冲突,导致PHP执行出错。而使用命名空间将代码放到唯一的厂商命名空间,我们的代码就可以和其他开发者使用相同的类名、接口名、函数或常量名。 当然如果你开发的是小型个人项目,只有少量的依赖,类名冲突可能不是问题,但是如果在团队中工作,开发用到许多第三方依赖的大型项目,就要认真对待命名冲突问题,因为你无法控制项目依赖在全局命名空间中引入的类、接口、函数和常量,这也是为什么要使用命名空间的原因。 3、声明命名空间 每个PHP类、接口、函数和常量都在命名空间中,声明命名空间很简单,在<?php标签后的第一行声明,声明语句以namespace开头,随后是一个空格,然后是命名空间的名称,最后以;结尾。 命名空间经常用于设置顶层厂商名,比如我们设置厂商名为LaravelAcademy:

在这个命名空间声明语句后声明的所有PHP类、接口、函数和常量都在LaravelAcademy命名空间中,而且和Laravel学院有某种关系。如果我们想组织学院用到的代码该怎么做呢?答案是使用子命名空间。 子命名空间的声明方式和前面的示例完全一样,唯一的区别是我们要使用\符号把命名空间和子命名空间分开,例如:

这个命名空间后的所有类、接口、函数和常量都位于LaravelAcademy\ModernPHP中。 在同一个命名空间中的类没必要在同一个PHP文件中声明,可以在PHP文件的顶部指定一个命名空间或子命名空间,此时,这个文件的代码就是该命名空间或子命名空间的一部分。因此我们可以在不同文件中编写属于同一个命名空间的多个类。 注:厂商命名空间是最顶层的命名空间,也是最重要的命名空间,用于识别品牌或组织,必须具有全局唯一性。子命名空间相对而言没那么重要,但是可以用于组织项目的代码。 4、导入和别名 在命名空间出现之前,PHP开发者使用Zend风格的类名解决命名冲突问题,这是一种类的命名方案,因Zend框架而流行,这种命名方案在PHP类名中使用下划线的方式表示文件系统的目录分隔符。这种约定有两个作用:其一,确保类名是唯一的;其二,原生的自动加载器会把类名中的下划线替换成文件系统的目录分隔符,从而确定文件的路径。例如,Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query类对应的文件是Zend/Cloud/DocumentService/Adapter/WindowsAzure/Query.php。可以看出,这种命名有个缺点:类名特别长。 现代的PHP命名空间也有这个问题,例如上述Response类完整的全名是Illuminate\Http\Response,幸好,我们可以通过导入以及创建别名的方式来改变这一状况。 导入的意思是指,在每个PHP文件中告诉PHP想使用哪个命名空间、类、接口、函数和常量,导入后就不用使用全名了:

我们通过use关键字告诉PHP,我们想使用Illuminate\Http\Response类,我们只需要输入一次完全限定的类名,随后实例化Response的时候,无需使用完整的类名。 如果觉得这样的类名还是长,可以创建别名。创建别名指的是告诉PHP我要使用简单的名称引用导入的类、接口、函数或常量:

从PHP 5.6开始还可以导入函数和常量,不过要调整use关键字的句法,如果要导入函数,需要使用use func:

如果想导入常量,可以使用use constant:

当然也支持别名,创建方式和类一样。 5、实用技巧 多重导入 如果想要在PHP文件中导入多个类、接口、函数或常量,需要在PHP文件的顶部使用多个use语句,PHP支持用简短的语法把多个use语句写成一行:

但是为了可读性,建议不要这么写,还是一行写一个use语句比较好:

一个文件使用多个命名空间 PHP允许在一个文件中定义多个命名空间:

但这么做不好,违背了“一个文件一个类”的良好实践,因此不建议这么做。 全局命名空间 如果引用的类、接口、函数和常量没有指定命名空间,PHP假定引用的类、接口、函数和常量在当前的命名空间中。如果要使用其他命名空间的类、接口、函数或常量,需要使用完全限定的PHP类名(命名空间+类名)。 有些代码在全局命名空间中,没有命名空间,比如原生的Exception类就是这样。在命名空间中引用全局的代码时,需要在类、接口、函数或常量前加\符号:

自动加载 命名空间还为PHP-FIG制定的PSR-4自动加载标准奠定了坚实的基础,大多数现代的PHP组件都使用了这种自动加载模式,使用依赖管理器Composer可以自动加载项目的依赖,后续我们还会详细介绍Composer和PHP-FIG,现在你只需要知道没有命名空间,就没有现代的PHP生态系统和基于组件的新型架构,由此可见命名空间的重要性。   from:http://laravelacademy.org/post/4221.html

龙生   13 Aug 2017
View Details

造成公众号支付闪退的几种原因

微支付里没有设置【JSAPI支付授权目录】 支付页面的【josn串】错误时,比如忘记配置APPID,或配置错了APPID,也会闪退。

龙生   12 Aug 2017
View Details

PhpStorm 常用设置和快捷键总结,持续更新~

常用设置: 去掉波浪线: settings -> Editor -> Colors & Fonts -> General -> TYPO->Effects 显示行号: settings -> Editor->Appearance->Show line numbers 去掉右上角浏览器图标: settings -> tools -> WebBrowsers 启动的时候不打开工程文件 Settings->General去掉Reopen last project on startup. 取消自动保存 appearance -> system settings -> save file的两个选项 去掉 常用快捷键: ctrl + f : 查找 ctrl + shift + f :查找任意内容,这个功能叼叼的~~ ctrl + r : 查找替换 ctrl + n : 查找类名称 ctrl + shift + n : 查找文件名称 ctrl + alt + shift + n : 查找方法名称 shift + shift :查找任意文件名称 ctrl + b: 跳到变量申明处 ctrl + […]

龙生   10 Aug 2017
View Details

laravel5.3搭建过程中出现问题

composer install命令出错-->

解决方法:因为镜像使用用的是http,而原地址是需要https,所以配置下关掉https就好了。

  报错信息:

解决方案:修改php.ini开启openssl拓展   Laravel 出现"RuntimeException inEncrypter.php line 43: The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths."问题的解决办法——> 首先在cmd命令行下定位到项目所在的根目录下,接着输入:

这时候项目根目录下的.env文件里的APP_KEY应该会有值了: 若没有,将上面的key输入进去 from:http://www.cnblogs.com/vincebye/p/5947739.html

龙生   06 Aug 2017
View Details

call_user_func_array

(PHP 4 >= 4.0.4, PHP 5, PHP 7) call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数 说明 mixed call_user_func_array ( callable $callback , array $param_arr ) 把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。 参数 callback 被调用的回调函数。 param_arr 要被传入回调函数的数组,这个数组得是索引数组。 返回值 返回回调函数的结果。如果出错的话就返回FALSE 更新日志 版本 说明 5.3.0 对面向对象里面的关键字的解析有所增强。在此之前,使用两个冒号来连接一个类和里面的一个方法,把它作为参数来作为回调函数的话,将会发出一个E_STRICT的警告,因为这个传入的参数被视为静态方法。 范例 Example #1 call_user_func_array()例子 <?php function foobar($arg, $arg2) { echo __FUNCTION__, " got $arg and $arg2\n"; } class foo { function bar($arg, $arg2) { echo __METHOD__, " got $arg and $arg2\n"; } } // Call the foobar() function with 2 arguments call_user_func_array("foobar", array("one", "two")); // Call the $foo->bar() method with 2 arguments $foo = new foo; call_user_func_array(array($foo, "bar"), array("three", "four")); ?> 以上例程的输出类似于:

Example #2 call_user_func_array()使用命名空间的情况 <?php namespace Foobar; class Foo { static public function test($name) { print "Hello {$name}!\n"; } } // As of PHP 5.3.0 call_user_func_array(__NAMESPACE__ .’\Foo::test', array('Hannes')); // As of PHP 5.3.0 call_user_func_array(array(__NAMESPACE__ .’\Foo', 'test'), array('Philip')); ?> 以上例程的输出类似于:

Example #3 把完整的函数作为回调传入call_user_func_array() <?php $func = function($arg1, $arg2) { return $arg1 * $arg2; }; var_dump(call_user_func_array($func, array(2, 4))); /* As of PHP 5.3.0 */ ?> 以上例程会输出:

Example #4 传引用 <?php function mega(&$a){ […]

龙生   18 Jul 2017
View Details

iWshop完整安装指南

本文档仅介绍如何安装iWshop并且完成微信公众号对接,其他微信认证、微信支付等申请可以参考: 百度经验 微信认证申请、微信支付申请 iWshop 交流群:470442221 iWshop 类文档:http://docs.ycchen.cc/iwshop/index.html 一、准备工作 服务器环境要求 PHP5.3+ MySQL 5.5.3+ (utf8mb4编码用于保存带有emoji表情的微信用户昵称) PHP扩展:php_mysql php_curl php_pdo_mysql php_mcrypt php_gd2 请确保您的php.ini配置中magic_quotes_gpc为Off,否则某些功能可能无法使用 如果需要redis,请加载php_redis扩展 iWshop是以UrlQuery的形式组合参数的,所以不需要伪静态模块。 开始安装iWshop http://git.oschina.net/koodo/iWshop/releases 现在以安装目录F:\dev_project\test_iwshop为例进行安装,我的httpd-vhosts.conf其中的一个设置是这样的。关于如何使用apache的vhosts可以参考:Apache官方示例 1 2 3 4 5 6 7 8 9 10 &lt;VirtualHost *:80&gt;     DocumentRoot "F:\dev_project\test_iwshop"     ServerName test.iw.com     &lt;Directory "F:\dev_project\test_iwshop"&gt;         AllowOverride All         Options FollowSymLinks         Order allow,deny         Allow from all     &lt;/Directory&gt; &lt;/VirtualHost&gt; 当然你也可以直接放服务器根目录。 然后在浏览器中打开localhost,或者vhosts指向的域名。 填写微店名称(可以在后台修改),数据库密码,后台管理员账号密码(可以在后台修改),然后点击下一步。 这里特别说明一下系统根目录,如果是在DocumentRoot的根目录下安装,那么就是 / ,如果是在某个子目录比如/iw/,那么这里就要填写 /iw/ ,一般情况下都会自动获取,无需填写,如果遇到css或者js等静态文件无法加载页面错乱的问题,请检查config.php里面的docroot选项。 点击马上安装,如果数据库版本和php环境没有什么配置问题的话,就安装成功了。 假设服务器域名是:www.iwshop.cn,那么你的: 后台地址:http://www.iwshop.cn/?/Wdmin/login/ 微信消息接口地址:http://www.iwshop.cn/wechat/ 二、微信对接 // todo 三、bug反馈 http://git.oschina.net/koodo/iWshop/issues iWshop 交流群:470442221 作者邮箱 koodo@qq.com from:http://git.oschina.net/koodo/iWshop/blob/dev/html/docs/install.md

龙生   16 May 2017
View Details

yii2 urlManager url美化及apache下yii2 rewrite设置

[摘要:远期正在进修yii2框架的应用,正在看他人的专客时讲到了好化url的完成 比方,默许进进about页里的时间,url是如许的http://localhost/index.php?r=site%2Fabout,只需正在/config/web.p] 近期在学习yii2框架的使用,在看别人的博客时讲到了美化url的实现 比如,默认进入about页面的时候,url是这样的http://localhost/index.php?r=site%2Fabout,只要在/config/web.php中,在components数组中加上 urlManager => [ showScriptName => false, enablePrettyUrl => true ], 开启之后再访问about页面,路径已变为http://localhost/web/site/about 但是我在本机上使用的时候,一直报404错误,搜索过后才知道是因为apache没有开启rewrite功能 最后找到了这个博客 http://www.chenruixuan.com/archives/759.html yii basic版: 1. 开启 apache 的 mod_rewrite 模块 去掉LoadModule rewrite_module modules/mod_rewrite.so前的“#”符号; 2. 修改 apache 的 AllowOverride 把 AllowOverride None 修改为 AllowOverride All; 3. 在与index.php文件同级目录(web目录)下添加文件“.htaccess” Options +FollowSymLinks IndexIgnore */* RewriteEngine on # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # otherwise forward it to index.php RewriteRule . index.php 4. 配置应用的urlManager   yii2.0与之前版本配置略有不同,根据文档显示: http://www.yiiframework.com/doc-2.0/yii-web-urlmanager.html 需要在config/web.php中的components数组下增加: 1 2 3 4 5 6 7 8 […]

龙生   16 May 2017
View Details

PHP实现RIJNDAEL_256加密(静态类)

 

龙生   15 May 2017
View Details

仿冒IP与伪造referer

伪造IP与伪造referer 在http协议中伪造ip的可能性研究 些日子对自定义http协议的各个数据进行了研究,对于ip伪造的问题,我当时给的建议是使用代理服务器,不过后来发现,其实可以在http协议加入一个选项,来实现一个非伪造ip的伪造ip 。如何理解呢?理由如下:~ 一、方法概述 在http协议数据头里面加入选项“x-forward-for”,例如:“x-forward-for:202.204.76.254”,这样发送出去 的包,就是一个特殊的包,在收包方看来,这个包的意思是,一个代理服务器发过来的数据包,而这个包的真是ip是“202.204.76.254”,其实还 是实现的是三次握手,但是只不过是在发包的同时,对收包方提到了一个第三者。 二、试用范围 因为现在的网站类的程序如果有IP限制的话,基本上都是会检测是不是代理服务器发送的数据的,如果是代理服务器发送的数据,那么他就把IP记为这个(透明)代理服务器发送的x-forward-for的IP。 以一段较为流行的php检测ip的代码为例: 那么大家可以看到这个IP是如何伪造的了。 三、应对方法 当然对于网站方面,这种伪造ip的情况虽然不是很多,但是如果在投票类的程序中,当然很需要这方面的检测了,呵呵。多多检测HTTP_CLIENT_IP吧。貌似这个还没有办法伪造? .. 四、总体看法 这个办法之所以称之为非伪造ip的伪造ip,主要就是利用了现在大多数网站程序检测ip的一个漏洞。所以如果网站程序能够重新审视一下自己的ip检测办法,这个方法就会慢慢失效的。呵呵。 – 伪造 referer 首先说明,伪造访问来路不是什么光明正大的事情,目的就是为了欺骗服务器。原本以为给 XMLHTTP 对象增加一个 Referer 的header 就可以,结果却没有任何作用,改用 ServerXMLHTTP 也如此。 无意间发现公司内部项目使用的 paypal 扣款程序里面有 WinHttp.WinHttpRequest.5.1 对象,它负责把客户的信用卡信息提交到 paypal 的服务器,看来是一个核心的远程访问方法,google一下发现它居然用可以成功伪造所有 http 请求的 header 信息!下面的代码通过伪造 referer 的值,假装从百度首页提交一个表单到指定的 url 去: var url = http://www.yourtarget.com ; var param = name=david&age=30 ; var obj = new ActiveXObject( WinHttp.WinHttpRequest.5.1 ); obj.Open( POST , url, false); obj.Option(4) = 13056; obj.Option(6) = false; //false可以不自动跳转,截取服务端返回的302状态。 obj.setRequestHeader( Content-Type , application/x-www-form-urlencoded ); obj.setRequestHeader( Referer , http://www.baidu.com ); obj.Send(param); WScript.Echo(obj.responseText); 保存为 xxx.js 文件,在命令行中运行 cscript.exe […]

龙生   15 May 2017
View Details
1 14 15 16 26