分类目录归档:PHP

PHP源码,PHP扩展,PHP程序

反转UTF8编码中文字符串的2种方法

反转UTF8编码中文字符串的2种方法

某天查手册时,看到strrev函数下面有一个 utf8_strrev函数的实现,觉得有些意思,于是自己使用mb开头的函数写了另一个实现。
【第一种方案】
使用正则匹配出所有的内容到数组,然后使用数组中的反转函数将整个数组反转,然后将数组转化成字符串
其代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
<?php
header("Content-type:text/html;charset=utf-8");
 
$str = "bb我是中国人aaaa";
 
/**
* 反转utf8的字符串,使用正则和数组实现
* @param string $str
* @return string
*/
function utf8_strrev($str){
  preg_match_all('/./us', $str, $ar);
  return implode('', array_reverse($ar[0]));                                                   
}
echo utf8_strrev($str), '<br />';

其中正则的两个修正符的说明如下:
u (PCRE_UTF8)
此修正符启用了一个 PCRE 中与 Perl 不兼容的额外功能。模式字符串被当成 UTF-8。本修正符在 Unix 下自 PHP 4.1.0 起可用,在 win32 下自 PHP 4.2.3 起可用。
s (PCRE_DOTALL)
如果设定了此修正符,模式中的圆点元字符(.) 匹配所有的字符,包括换行符。没有此设定的话,则不包括换行符。这和 Perl 的 /s 修正符是等效的。排除字符类例如 [^a] 总是匹配换行符的,无论是否设定了此修正符。

【第二种方案】
使用Multibyte String Functions实现
算出字符串在utf8ut编码下的长度,倒序取每个utf8字符,连接起来,返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
header("Content-type:text/html;charset=utf-8");
 
$str = "bb我是中国人aaaa";
 
/**
* 反转utf8的字符串,使用mb开头的函数
* @param string $str
* @return string
*/
function mb_strrev($str) {
    $len = mb_strlen($str, 'UTF-8');
    $string = '';
    for ($i = $len - 1; $i >= 0; $i--) {
       $string .= mb_substr($str, $i, 1, 'UTF-8');                                                         
    }
    return $string;
}
 
echo mb_strrev($str);

最后一句:多看手册

Google Adwords API开发环境问题

Google Adwords API开发环境问题

最近接手系统中Google Adwords API的开发,然后需要取广告系统的数据,当一切准备就绪后,自己写了代码,发现根本没有取到数据,到最后是有一些必要的扩展没有打开。
需要扩展列表如下:
【soap扩展】
如果soap扩展没有打开,则会报错如下:
Fatal error: This client library requires the SOAP extension to be activated. See http://php.net/manual/en/soap.installation.php for details. in aw_api\src\Google\Api\Ads\Common\Lib\SoapClientFactory.php on line 93
打开方式:在php.ini中将 extension=php_soap.dll前面的分号去掉

【openssl扩展】
如果opensslpss扩展没有找开,则会报错如下:
Warning: SoapClient::SoapClient() [soapclient.soapclient]: Unable to find the wrapper “https” – did you forget to enable it when you configured PHP? in aw_api\src\Google\Api\Ads\Common\Lib\AdsSoapClient.php on line 142
Warning: SoapClient::SoapClient() [soapclient.soapclient]: I/O warning : failed to load external entity “https://adwords.google.com/api/adwords/cm/v200909/CampaignService?wsdl” in aw_api\src\Google\Api\Ads\Common\Lib\AdsSoapClient.php on line 142

打开方式:在php.ini中将 extension=php_openssl.dll前面的分号去掉

【curl扩展】
如果curl扩展没有找开,则会报错如下:
Fatal error: Call to undefined function curl_init() in aw_api\src\Google\Api\Ads\Common\Util\AuthToken.php on line 103
打开方式:在php.ini中将 extension=php_curl.dll前面的分号去掉

其实到最后,发现这些本来就是应该打开的扩展,google使用https,这就必须要开启 openssl,我们使用wsdl,就必须要开启soap

是受http://blog.csdn.net/cooledit2730/archive /2010/05/22/5616134.aspx的启发,才发现有扩展没有打开的。一直以为是自己的代码问题。感谢

PHP设计模式笔记:使用PHP实现工厂模式

PHP设计模式笔记:使用PHP实现工厂模式

【意图】
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使用一个类的实例化延迟到其子类【GOF95】

【工厂模式结构图】

工厂方法模式

工厂方法模式

【工厂模式中主要角色】
抽象产品(Product)角色:具体产品对象共有的父类或接口
具体产品(Concrete Product)角色:实现抽象产品角色所定义的接口,并且工厂方法模式所创建的每一个对象都是某具体产品对象的实例
抽象工厂(Creator)角色:模式中任何创建对象的工厂类都要实现这个接口,它声明了工厂方法,该方法返回一个Product类型的对象。
Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的的ConcreteProduct对象
具体工厂(Concrete Creator)角色:实现抽象工厂接口,具体工厂角色与应用逻辑相关,由应用程序直接调用以创建产品对象。

【工厂模式的优点和缺点】
工厂模式的优点
工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。

工厂模式的缺点
客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建一个Creator子类

【工厂模式适用场景】
1、当一个类不知道它所必须创建的对象的类的时候
2、当一个类希望由它的子类来指定它所创建的对象的时候
3、当类将创建对象的职责委托给多个帮助子类的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候

【工厂模式与其它模式】
抽象工厂模式(abstract factory模式):Abstract Factory模式经常使用工厂方法来实现
Template Method模式: 工厂方法通常在Template Methods中被调用

【工厂模式PHP示例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
 
<?php
/**
 * 工厂模式 2010-06-25 sz
 * @author 胖子 phppan.p#gmail.com  http://www.phppan.com
 * 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
/**
 * 抽象工厂角色
 */
interface Creator {
    public function factoryMethod();
}
 
/**
 * 具体工厂角色A
 */
class ConcreteCreatorA implements Creator {
 
    /**
     * 工厂方法 返回具体 产品A
     * @return ConcreteProductA
     */
    public function factoryMethod() {
        return new ConcreteProductA();
    }
}
 
/**
 * 具体工厂角色B
 */
class ConcreteCreatorB implements Creator {
 
    /**
     * 工厂方法 返回具体 产品B
     * @return ConcreteProductB
     */
    public function factoryMethod() {
        return new ConcreteProductB();
    }
}
 
/**
 * 抽象产品角色
 */
interface Product {
    public function operation();                                                                                    
}
 
/**
 * 具体产品角色A
 */
class ConcreteProductA implements Product {
 
    /**
     * 接口方法实现 输出特定字符串
     */
    public function operation() {
        echo 'ConcreteProductA <br />';
    }
}
 
/**
 * 具体产品角色B
 */
class ConcreteProductB implements Product {
 
    /**
     * 接口方法实现 输出特定字符串
     */
    public function operation() {
        echo 'ConcreteProductB <br />';
    }
}
 
class Client {
 
    /**
     * Main program.
     */
    public static function main() {
        $creatorA = new ConcreteCreatorA();
        $productA = $creatorA->factoryMethod();
        $productA->operation();
 
        $creatorB = new ConcreteCreatorB();
        $productB = $creatorB->factoryMethod();
        $productB->operation();
    }
 
}
 
Client::main();
?>

【工厂方法模式与简单工厂模式】
工厂方法模式与简单工厂模式再结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了”开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
工厂方法模式退化后可以演变成简单工厂模式。