PHP设计模式初探-详解单例模式

2012年4月20日 Airy 没有评论

常见的设计模式有 24 种,其实就常规开发来说,了解其中的七八种就足够了。工厂模式是最常见的,一般初学面向对象首先接触的就是工厂模式,不多废话。

单例模式( wikipedia )是指类只维持一个实例化后的对象,特别适合于创建数据库链接。使用单例模式维护数据库链接能够避免重复建立数据库链接,在单一进程中节省不必要的资源消耗。

要做到在同一个进程中维护同一个资源,可能首先想到的是一个全局变量。一旦这个全局变量在外部被修改了,那么单例模式就完全失效了。要理解单例模式,首先要搞懂静态变量的概念。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
function test() {
 
$a = 0;
 
static $a;
 
$a += 1;
 
return $a;
 
}
 
echo test();
 
echo test();

由以上程序的运行结果可以得知,static 关键字使得变量成为一个静态变量。
对于静态局部变量来说,在函数内以static声明的变量虽然与自动局部变量的作用域相同(即作用域都只限于函数内),但存储空间是以静态分配而非默认的自动分配方式获取的,因而存储空间所在区域不同(一般来说,静态分配时存储空间于编译时在程序数据段分配,一次分配全程有效;而自动分配时存储空间则是于调用栈上分配,只在调用时分配与释放),且两次调用间变量值始终保持一致;(via: wikipedia

有了静态变量,我们就可以实现一个完整的单例模式了。

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
 
require_once("DB.php");
 
class DatabaseConnection
{
  public static function get()
  {
    static $db = null;
    if ( $db == null )
      $db = new DatabaseConnection();
    return $db;
  }
 
  private $_handle = null;
 
  private function __construct()
  {
    $dsn = 'mysql://root:password@localhost/photos';
    $this->_handle =& DB::Connect( $dsn, array() );
  }
 
  public function handle()
  {
    return $this->_handle;
  }
}
 
print( "Handle = ".DatabaseConnection::get()->handle()."\n" );
print( "Handle = ".DatabaseConnection::get()->handle()."\n" );
分类: 未分类 标签:

Ucenter接入其他应用

2012年3月9日 Airy 1 条评论

实现接入需要完成两种类型的通讯:
一. 将应用的操作同步到ucenter(注册新用户等)
二. 应用能正确的响应ucenter发来的通知(用户在其他地方已经登陆、在其他地方修改了个人资料等)

第一种类型的操作对应的代码

/**
下列文件中需要定义以下常量:
define('UC_CONNECT', 'mysql');
define('UC_DBHOST', '127.0.0.1');
define('UC_DBUSER', 'root');
define('UC_DBPW', 'okm');
define('UC_DBNAME', 'x2');
define('UC_DBCHARSET', 'utf8');
define('UC_DBTABLEPRE', '`x2`.pre_ucenter_');
define('UC_DBCONNECT', '0');
define('UC_KEY', 'root');
define('UC_API', 'http://localhost/x2/uc_server');
define('UC_CHARSET', 'utf-8');
define('UC_IP', '');
define('UC_APPID', '2');
define('UC_PPP', '20');
**/

require 'path/to/someUcenterConstantsConfig.php';
require 'path/to/uc_client/client.php';

 

//尝试使用 client.php 中定义的方法同步应用的消息到ucenter端
$uid = uc_user_register('airylinus', 'helloucenter', 'helloucenter@frommyapp.com');
var_dump($uid);

如果没有以为,此时的 ucenter 用户管理模块已经可以看到一个新的名为 “airylinus” 的用户了。

第二种类型的操作的实现代码

1. 配置ucenter用户管理中心的应用列表
关键字段:应用的主 URL、应用接口文件名称
最终结果需要保证 “应用的主 URL” + “/api/” + “应用接口文件名称” = “http://yourAppHost/path/to/serviceForUcenter.php” (多么脑残的两个配置字段啊!)

2. serviceForUcenter.php需要按照约定响应ucenter的通知
以ucenter开发文档中的 api 目录为例,其中的 uc.php 定义了一个简单的响应接口。

//修改 uc.php 文件
error_reporting(E_ALL);

点击ucenter用户中心的“应用管理”标签,如果通讯失败就去php错误日志找报错原因然后解决,直至显示通信成功。

注意事项:
用户登录成功之后返回的 javascript 代码需要放到html页面中。

分类: 未分类 标签:

生成分页链接的函数

2011年12月6日 Airy 没有评论

$total = 59;
$size = 10;
$now = 1;
$url = "";

echo GenPaginationString($url, $total, $size, 6);

function GenPaginationString($url, $total, $size, $now) {
	$offSet = 4;
	$outString = $urlPrefix = $urlSuffix = "";
	$pageCount = ceil($total/$size);
	if (is_array($url)) {
		$urlPrefix = $url[0];
		$urlSuffix = $url[1];
	}
	if ($pageCount > 1) {
		$from = (($pageCount < (2*$offSet + 1)) or ($now <= $offSet)) ? 1 : ($now - $offSet);
		$to = ($pageCount < ($now + $offSet + 1)) ? $pageCount : ($now + $offSet + 1);
		for ($i = $from ; $i <= $to; $i++) {
			$outString .= ($now == $i) ? "  $i" : "  $i";
		}
	}
	return $outString;
}
分类: 未分类 标签:

php静态方法 vs 构造函数

2011年11月28日 Airy 没有评论

调用静态方法时构造函数会不会执行呢?
写一个简单的例子测试下就知道结果了:

?Download test.php
1
2
3
4
5
6
7
8
9
10
11
12
13
 
error_reporting(E_ALL);
 
class test {
	public function __construct() {
		echo "echo from function __construct() ";
	}
 
	public static function ttt() {
		echo 'from static function ttt()';
	}
}
test::ttt();

由结果可以知道,静态方法不会实例化对象,也不会尝试执行构造函数

分类: 未分类 标签:

Gvim 配置文件备份

2011年11月15日 Airy 没有评论
?Download download.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
set langmenu=en_US
let $LANG = 'en_US'
 
set go= "设置没有gui界面
set number "显示行号
set autoindent "使用对齐格式,也就是把当前行的的对齐格式应该到下一行。
set smartindent "依据上面的对齐格式,智能的选择对齐方式。
set tabstop=4 "设置tab键为4个空格。
set shiftwidth=4 "设置当行之间交错时使用4个空格。
set ruler "设置在编辑过程中,在右下角显示光标位置的状态行。
set showmatch "高亮显示匹配的括号。
syntax enable "开启语法
syntax on "高亮语法
set nobackup "设置没有备份文件。
set cursorline "高亮当前行
"set cursorcolumn "高亮纵向行
set statusline=%h%=%-14.(%l,%c%V%)\ %&lt;%p%%\ \ \ [%L]\ \ \ %{strftime('%y-%m-%d\ %A')}
set encoding=utf-8 "设置编码文件
set fileencodings=utf-8,gb2312,gbk,gb18030,latin-1 "设置文件编码
set fileencodings=ucs-bom,utf-8,cp936
set fileencoding=utf-8
colorscheme murphy
 
cd d:xampp\htdocs\
分类: 未分类 标签:

windows 下 nginx + php 环境配置

2011年11月14日 Airy 没有评论

1. 在官方网站下载 nginx 和 php,php 运行cgi有版本限制。

2. 首先需要启动 php-cgi.exe ,监听指定端口。解析php,返回结果。参数可以用 php-cgi.exe -help察看。一般情况下 php-cgi.exe -b 9999 -d path/to/php.ini

3. 修改nginx 的配置文件,获取针对php文件的请求,并将文件传到 php-cgi.exe 进行解析处理,将结果返回客户端。

php.ini中需要修改的参数有:

doc_root =  path/to/webroot    //网站根目录物理路径

cgi.fix_pathinfo=0  //该选项不能打开,否则会有问题。

4. 模拟path_info 参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
location ~ \.php {
    # define php file directory
    root           "D:\work\www";
    # pass cgi request to php-cgi
    fastcgi_pass   127.0.0.1:9999;
    # default index file
    fastcgi_index  index.php;
    # set $_SERVER['SCRIPT_FILENAME']
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    # include other params
    include        fastcgi_params;
    set $path_info "";
    set $real_script_name $fastcgi_script_name;
    if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
        set $real_script_name $1;
        set $path_info $2;
    }
    fastcgi_param SCRIPT_NAME $real_script_name;
    fastcgi_param PATH_INFO $path_info;
}

5. 方便的控制服务器启动和停止

start.bat

@echo off
echo Starting PHP FastCGI…
RunHiddenConsole.exe d:\work\php\php-cgi.exe -b 127.0.0.1:9999 -c d:\work\php\php.ini
echo Starting nginx…
RunHiddenConsole.exe d:\work\nginx\nginx.exe -p D:\work\nginx

stop.bat

@echo off
echo Stopping nginx…
taskkill /F /IM nginx.exe > nul
echo Stopping PHP FastCGI…
taskkill /F /IM php-cgi.exe > nul
echo done.

分类: 未分类 标签:

Yii step by step

2011年10月11日 Airy 没有评论

建立基本目录,使用 index.php 驱动框架。配置 config,驱动数据库。

首先我想实现 wordpress 那种可以在后台设置 theme ,因为我想快速灵活的控制模板样式。

模板文件放在 /theme 下,每个风格有独立的 views 目录。 views/layouts 为该风格的 layout 文件,其他类似每个controller 有一个文件夹,然后每个action有一个 {actionName}.php 的文件。

在controller 里面使用 Yii::app()->theme = ‘xxx’ 启用主题,之后就可以使用 $this->layout = ‘xxx’ 使用对应主题下的 layout

分类: 未分类 标签:

衣不如新,人不如旧

2011年9月11日 Airy 没有评论

我一直都在用一种消尽量极的态度对待身边一切,很少主动。如果不是必须买新衣服,我倒觉得旧衣服挺好的。
偶尔会想起来某些事情,有些时候一个名字到了嘴边又咽下去,更甚至会怀疑现在的自己是不是真的开心。自始至终,这些念头没有表现出来过。因为我相信,再强烈的感情,只要不去反复刺激,都会在时光中泯灭。只是偶尔会羡慕,羡慕那些能够畅快琳琳的表达自己情绪的人。

分类: 未分类 标签:

使用git和github管理代码

2011年9月8日 Airy 没有评论

建立本地git仓库

首先,git要求使用者必须提供自己的身份标识,为此我们需要在git bash中执行以下命令:

git config –global user.name ‘yourname’
git config –global user.email youremail

建立项目并初始化git仓库

mkdir path/to/project
cd project
git init
执行此操作后,git将在project目录下创建一个隐藏目录(.git),这个目录就是git用来管理软件版本的仓库。

使用git管理项目

#cp somethingelse ./
git add .
git commit -m “这是我们第一次初始化项目”

git add命令可以将参数指定的文件添加到git仓库索引中,如果你一次添加太多文件可以使用:git add . 命令全部添加。

git commit命令才是真正的将文件添加到git仓库中去,-m选项允许在命令行后直接给出每次添加的简短说明(PS:我们强烈推荐你再每次提交时都给出一个说明,以便项目版本的查阅等),如果没有给出此命令将调用默认文本编辑器以便你添加说明。

项目提交到github管理

要想将本地的git项目提交到github我们需要先在github添加此项目,登入github主页点击“create a new one”根据提示完成项目创建。刚创建好的项目不包含任何文件,我们需要稍作设置后方可使用。

1,在git bash中执行以下命令创建密钥:

ssh-keygen -C ‘mymail@gmail.com’ -t rsa

一路按Enter键即可,当然如果你想选择使用密码功能,那么在提示输入密码是选择你自己的密码。过程如下图所示:
2,找到刚才生成的密钥(id_rsa.pub)文件并用文本编辑器打开,然后复制里面的内容。接着转到github站点项目编辑(edit),找到”Deploy keys“选项后点击”add another deploy key“并将刚才复制的内容黏贴保存。

3,测试SSH连接。在git bash中执行以下命令:

SSH -v git@github.com

如果提示你的密钥不正确,那么你需要重新确认上一步的操作是否完整无误。

4,如果上一步测试无错,那么现在就可以将本地的文件提交到github仓库了。在git bash中执行以下命令:
git remote add alias git@github.com:yourgithubaccountname/yourgithubreponame.git
git push alias bruncknamedefaultismaster

分类: 未分类 标签:

设计模式学习之单例模式-singleton

2011年9月7日 Airy 没有评论
分类: 未分类 标签: