php - apc和文件缓存类

// 收集到的一篇不错的PHP缓存实现。实现了apc和文件缓存,继承Cache_Abstract即可实现调用第三方的缓存工具。

<?php
class CacheException extends Exception {}
/**
* 缓存抽象类
*/
abstract class Cache_Abstract {
/**
     * 读缓存变量
     *
     * @param string $key 缓存下标
     * @return mixed
     */
     abstract public function fetch($key);

/**
     * 缓存变量
     *
     * @param string $key 缓存变量下标
     * @param string $value 缓存变量的值
     * @return bool
     */
     abstract public function store($key, $value);

/**
     * 删除缓存变量
     *
     * @param string $key 缓存下标
     * @return Cache_Abstract
     */
     abstract public function delete($key);

/**
     * 清(删)除所有缓存
     *
     * @return Cache_Abstract
     */
     abstract public function clear();

/**
     * 锁定缓存变量
     *
     * @param string $key 缓存下标
     * @return Cache_Abstract
     */
     abstract public function lock($key);
/**
     * 缓存变量解锁
     *
     * @param string $key 缓存下标
     * @return Cache_Abstract
     */
     abstract public function unlock($key);
/**
     * 取得缓存变量是否被锁定
     *
     * @param string $key 缓存下标
     * @return bool
     */
     abstract public function isLocked($key);
/**
     * 确保不是锁定状态
     * 最多做$tries次睡眠等待解锁,超时则跳过并解锁
     *
     * @param string $key 缓存下标
     */
     public function checkLock($key) {
         if (!$this->isLocked($key)) {
         return $this;
         }
         
             $tries = 10;
             $count = 0;
             do {
                 usleep(200);
                 $count ++;
             } while ($count <= $tries && $this->isLocked($key));     // 最多做十次睡眠等待解锁,超时则跳过并解锁
             $this->isLocked($key) && $this->unlock($key);
             
             return $this;
     }
}

/**
* APC扩展缓存实现
*
*
* @category     Mjie
* @package     Cache
* @author         流水孟春
* @copyright     Copyright (c) 2008- <cmpan(at)qq.com>
* @license     New BSD License
* @version     $Id: Cache/Apc.php 版本号 2010-04-18 23:02 cmpan $
*/
class Cache_Apc extends Cache_Abstract {

protected $_prefix = 'cache.mjie.net';

public function __construct() {
     if (!function_exists('apc_cache_info')) {
     throw new CacheException('apc extension didn\'t installed');
     }
}

/**
     * 保存缓存变量
     *
     * @param string $key
     * @param mixed $value
     * @return bool
     */
public function store($key, $value) {
         return apc_store($this->_storageKey($key), $value);
}

/**
     * 读取缓存
     *
     * @param string $key
     * @return mixed
     */
public function fetch($key) {
         return apc_fetch($this->_storageKey($key));
}

/**
     * 清除缓存
     *
     * @return Cache_Apc
     */
public function clear() {
     apc_clear_cache();
     return $this;
}

/**
     * 删除缓存单元
     *
     * @return Cache_Apc
     */
public function delete($key) {
         apc_delete($this->_storageKey($key));
         return $this;
}

/**
     * 缓存单元是否被锁定
     *
     * @param string $key
     * @return bool
     */
public function isLocked($key) {
     if ((apc_fetch($this->_storageKey($key) . '.lock')) === false) {
         return false;
     }
     
     return true;
}

/**
     * 锁定缓存单元
     *
     * @param string $key
     * @return Cache_Apc
     */
public function lock($key) {
     apc_store($this->_storageKey($key) . '.lock', '', 5);
     return $this;
}

/**
     * 缓存单元解锁
     *
     * @param string $key
     * @return Cache_Apc
     */
public function unlock($key) {
     apc_delete($this->_storageKey($key) . '.lock');
     return $this;
}

/**
     * 完整缓存名
     *
     * @param string $key
     * @return string
     */
private function _storageKey($key) {
         return $this->_prefix . '_' . $key;
}
}
/**
* 文件缓存实现
*
*
* @category     Mjie
* @package     Cache
* @author         流水孟春
* @copyright     Copyright (c) 2008- <cmpan(at)qq.com>
* @license     New BSD License
* @version     $Id: Cache/File.php 版本号 2010-04-18 16:46 cmpan $
*/
class Cache_File extends Cache_Abstract {

protected $_cachesDir = 'cache';

public function __construct() {
     if (defined('DATA_DIR')) {
     $this->_setCacheDir(DATA_DIR . '/cache');
     }
}

/**
     * 获取缓存文件
     *
     * @param string $key
     * @return string
     */
protected function _getCacheFile($key) {
     return $this->_cachesDir . '/' . substr($key, 0, 2) . '/' . $key . '.php';
}
     /**
     * 读取缓存变量
     * 为防止信息泄露,缓存文件格式为php文件,并以"<?php exit;?>"开头
     *
     * @param string $key 缓存下标
     * @return mixed
     */
     public function fetch($key) {
             $cacheFile = self::_getCacheFile($key);
             if (file_exists($cacheFile) && is_readable($cacheFile)) {
                 return unserialize(@file_get_contents($cacheFile, false, NULL, 13));
             }
             return false;
     }
/**
     * 缓存变量
     * 为防止信息泄露,缓存文件格式为php文件,并以"<?php exit;?>"开头
     *
     * @param string $key 缓存变量下标
     * @param string $value 缓存变量的值
     * @return bool
     */
     public function store($key, $value) {
     $cacheFile = self::_getCacheFile($key);
     $cacheDir     = dirname($cacheFile);
     if(!is_dir($cacheDir)) {
         if([url=mailto:!@mkdir($cacheDir]!@mkdir($cacheDir[/url], 0755, true)) {
         throw new CacheException("Could not make cache directory");
         }
     }
             return @file_put_contents($cacheFile, '<?php exit;?>' . serialize($value));
}
/**
     * 删除缓存变量
     *
     * @param string $key 缓存下标
     * @return Cache_File
     */
     public function delete($key) {
         if(empty($key)) {
         throw new CacheException("Missing argument 1 for Cache_File::delete()");
     }
     
     $cacheFile = self::_getCacheFile($key);
     if([url=mailto:!@unlink($cacheFile]!@unlink($cacheFile[/url])) {
         throw new CacheException("Cache file could not be deleted");
     }
     return $this;
}
/**
     * 缓存单元是否已经锁定
     *
     * @param string $key
     * @return bool
     */
public function isLocked($key) {
     $cacheFile = self::_getCacheFile($key);
     clearstatcache();
     return file_exists($cacheFile . '.lock');
}
/**
     * 锁定
     *
     * @param string $key
     * @return Cache_File
     */
public function lock($key) {
     $cacheFile = self::_getCacheFile($key);
     $cacheDir     = dirname($cacheFile);
     if(!is_dir($cacheDir)) {
         if([url=mailto:!@mkdir($cacheDir]!@mkdir($cacheDir[/url], 0755, true)) {
         if(!is_dir($cacheDir)) {
                 throw new CacheException("Could not make cache directory");
         }
         }
     }
     // 设定缓存锁文件的访问和修改时间
     @touch($cacheFile . '.lock');
     return $this;
}
     
/**
     * 解锁
     *
     * @param string $key
     * @return Cache_File
     */
public function unlock($key) {
     $cacheFile = self::_getCacheFile($key);
         @unlink($cacheFile . '.lock');
     return $this;
}
/**
     * 设置文件缓存目录
     * @param string $dir
     * @return Cache_File
     */
protected function _setCacheDir($dir) {
     $this->_cachesDir = rtrim(str_replace('\\', '/', trim($dir)), '/');
     clearstatcache();
     if(!is_dir($this->_cachesDir)) {
     mkdir($this->_cachesDir, 0755, true);
     }
     //
     return $this;
}
     
/**
     * 清空所有缓存
     *
     * @return Cache_File
     */
public function clear() {
     // 遍历目录清除缓存
     $cacheDir = $this->_cachesDir;
     $d = dir($cacheDir);
     while(false !== ($entry = $d->read())) {
     if('.' == $entry[0]) {
     continue;
     }
     
     $cacheEntry = $cacheDir . '/' . $entry;
     if(is_file($cacheEntry)) {
     @unlink($cacheEntry);
     } elseif(is_dir($cacheEntry)) {
     // 缓存文件夹有两级
     $d2 = dir($cacheEntry);
     while(false !== ($entry = $d2->read())) {
         if('.' == $entry[0]) {
         continue;
         }
         
         $cacheEntry .= '/' . $entry;
         if(is_file($cacheEntry)) {
         @unlink($cacheEntry);
         }
     }
     $d2->close();
     }     
     }
     $d->close();
     
     return $this;
}
}
/**
* 缓存单元的数据结构
* array(
*         'time' => time(),     // 缓存写入时的时间戳
*         'expire' => $expire, // 缓存过期时间
*         'valid' => true,         // 缓存是否有效
*         'data' => $value         // 缓存的值
* );
*/
final class Cache {
/**
     * 缓存过期时间长度(s)
     *
     * @var int
     */
private $_expire = 3600;
/**
     * 缓存处理类
     *
     * @var Cache_Abstract
     */
private $_storage = null;
/**
         * @return Cache
         */
static public function createCache($cacheClass = 'Cache_File') {
     return new self($cacheClass);
}
private function __construct($cacheClass) {
     $this->_storage = new $cacheClass();
}
/**
     * 设置缓存
     *
     * @param string $key
     * @param mixed $value
     * @param int $expire
     */
public function set($key, $value, $expire = false) {
     if (!$expire) {
     $expire = $this->_expire;
     }
     
     $this->_storage->checkLock($key);
     
     $data = array('time' => time(), 'expire' => $expire, 'valid' => true, 'data' => $value);
     $this->_storage->lock($key);
     
     try {
     $this->_storage->store($key, $data);
     $this->_storage->unlock($key);
     } catch (CacheException $e) {
     $this->_storage->unlock($key);
     throw $e;
     }
}
/**
     * 读取缓存
     *
     * @param string $key
     * @return mixed
     */
public function get($key) {
     $data = $this->fetch($key);
     if ($data && $data['valid'] && !$data['isExpired']) {
     return $data['data'];
     }
     
     return false;
}
/**
     * 读缓存,包括过期的和无效的,取得完整的存贮结构
     *
     * @param string $key
     */
public function fetch($key) {
     $this->_storage->checkLock($key);
     $data = $this->_storage->fetch($key);
     if ($data) {
     $data['isExpired'] = (time() - $data['time']) > $data['expire'] ? true : false;
     return $data;
     }
     
     return false;
}
/**
     * 删除缓存
     *
     * @param string $key
     */
public function delete($key) {
     $this->_storage->checkLock($key)
                         ->lock($key)
                         ->delete($key)
                         ->unlock($key);
}

public function clear() {
     $this->_storage->clear();
}
/**
     * 把缓存设为无效
     *
     * @param string $key
     */
public function setInvalidate($key) {
     $this->_storage->checkLock($key)
                         ->lock($key);
     try {
     $data = $this->_storage->fetch($key);
     if ($data) {
     $data['valid'] = false;
     $this->_storage->store($key, $data);
     }
     $this->_storage->unlock($key);
     } catch (CacheException $e) {
     $this->_storage->unlock($key);
     throw $e;
     }
}

/**
     * 设置缓存过期时间(s)
     *
     * @param int $expire
     */
public function setExpire($expire) {
     $this->_expire = (int) $expire;
     return $this;
}
}

标签: 缓存, 变量, IT, 下标

thinkphp 使用技巧总结 - 快速入门

在比较了下Zend Framework、CakePHP等框架后,我认为ThinkPHP的开发效率最高,代码最为简洁,最适合中小型项目开发。


1. 模板中不能使用的标签
{$content} {$i}
2. If标签
如: <if condition="$name eq 1 ">
试验后总是有想不到的错误, 这样,还不如直接用<?php if(...){ ...?>来得快些呢.

约定:
1.所有类库文件必须使用.class.php作为文件后缀,并且类名和文件名保持一致
2.控制器的类名以Action为后 缀
3.模型的类名以Model为后缀,类名第一个字母须大写
4.数据库表名全部采用小写,

如:
数据表名: 前缀_表名
模型类名: 表名Model 注:这里的表名第一个字母要大写
创建对象: D('表名') 注:这里的表名第一个字母要大写

定义控制器类
class IndexAction extends Action{
    public function show(){
        echo '这是新的 show 操作';
    }
}
然后在浏览器里面输入
http://localhost/myApp/index.php/Index/show/


定义模型类:
class 表名Model extends Model{
[//手动定义字段[可选]
    protected $fields = array(
    'id',
    'username',
    'email',
    'age',
    '_pk'=>'id', //主键
    '_autoInc'=>true //是否自增
    )
]
}

记录的修改:
$User = D("User") // 实例化 User 对象
$User->find(1) // 查找 id 为 1 的记录
$User->name = 'ThinkPHP' // 把查找到的记录的名称字段修改为 ThinkPHP
$User->save() // 保存修改的数据
更新特定字段的值
$User->setField('name','TopThink','id=1')
同 样可以支持对字段的操作
$User->setField('score','(score+1)','id=1')


新建记录,方法1:
$User = new UserModel() //实例化 User 对象
$User->字 段名 = 字段值 //给字段赋值
$User->add() //添加记录
新建记录,方法2:
$data['字段名'] = 字段值; //给字段赋值
$User = D('User'); //实例化 User 对象
$User->add($data); //$insertId,Add 方法的返回值就是最新插入的主键值,可以直接获取。
新增多条记录:
$User = new UserModel()
$data[0]['name'] = 'ThinkPHP'
$data[0]['email'] = 'sjolzy@chen.com'
$data[1]['name'] = '流年'
$data[1]['email'] = 'chen@sjolzy.cn'
$User>addAll($data)


删除记录
$User->find(2)
$User->delete() // 删除查找到的记录
$User->delete('5,6') // 删除主键为 5、6 的数据
$User->deleteAll() // 删除查询出来的所有数据

记录查询

$User->getDbFields() //获取当前数据字段
$User->findAll(); //查找所有记录
$User->findAll('1,3,8') //查询主键为1,3,8的记录集
$User->count() // 获取记录数
$User->max('score') // 获取用户的最大积分
$User->min('score','score>0') // 获取积分大于 0 的用户的最小积分
$User->avg('字段名') // 获取所有记录的字段值的平均值
$User->sum('字段名 ') // 统计字段值
$User->getN(2,'score>80','score desc') // 返回符合条件的第 2 条记录
$User->getN(2,'score>80','score desc') //还可以获取最后第二条记录
$User->first('score>80','score desc') //如果要查询第一条记录,还可以使用
$User->last('score>80','score desc') // 获取最后一条记录
$User->top(5,'','score desc') // 获取积分最高的前 5 条记录
$User->getBy('name','liu21st') //跟据字段的字段值来查询记录

$Model = new Model() // 实例化一个 model 对象 没有对应任何数据表
$Model->query("select * from think_user where status=1")

$objrs = $Model->query("select * from think_user where status=1") //自定义查询
$Model->execute("update think_user set name='thinkPHP' where status=1") //用于更新和写入数据的 sql 操作,返回影响的记录数


$User->startTrans() // 启动事务
$User->commit() // 提交事务
$User->rollback() // 事务回滚

模板:

$this->assign('name',$value); //在 Action 类里面使用 assign 方法对模板变量赋值,无论何种变量类型都统一使用 assign 赋值

$this->display() // 输出模版文件

批量赋值
$array['name'] = 'thinkphp'
$array['email'] = 'chen@sjolzy.cn'
$array['phone'] = '12335678'
$this->assign($array)


$this->display() // 调用 User 模块的 read 操作模版
$this->display('edit') // 调用 User 模块的 edit 操作模版
$this->display('Member:read') // 调用 Member 模块的 read 操作模版
$this->display('Xp@User:edit') // 调用 Xp 主题的 User 模块的 edit 操作模版
$this->display('../Member/read.html') // 直接指定模版文件的全名

模板标签:

{ } 或 {// 注释内容 } //模板注释
{$user['name']} //输出数组变量
{$user:name} //输出对象的属性

为了方便模板定义,无论输出的模板变量是数组还是对象,都可以用下列统一方式输出:
{$user.name}
如果是多维数组或者多 层对象属性的输出,请使用下面的定义方式:
{$user['sub']['name']}
{$user:sub:name}

使用函数:
格式:{$varname|function1|function2=arg1,arg2,### }
说明:
{ 和 $ 符号之间不能有空格 ,后面参数的空格就没有问题
###表示模板变量本身的参数位置

系统变量
{$Think.server.script_name } //取得$_SERVER 变量
{$Think.session.session_id|md5 } // 获取$_SESSION 变量
{$Think.get.pageNumber } //获取$_GET 变量
{$Think.cookie.name } //获取$_COOKIE 变量
系统常量
{$Think.const.__FILE__ }
{$Think.const.MODULE_NAME }
特殊变量 ,由 ThinkPHP 系统定义的常量
{$Think.version } //版本
{$Think.now } //现在时间

快捷输出
{:function(…)} //执行方法并输出返回值
{~function} //执行方法不输出
{@var} //输出 Session 变量
{&var} //输出配置参数
{%var} //输出语言变量
{.var} //输出 GET 变量
{^var} //输出 POST 变量
{*var} //输出常量

包含外部文件
<include file="$tplName" /> // 用变量控制要导入的模版
<include file="../Public/header.html" /> // 使用一个完整的文件名包含

循环输出
iterate 还有其它的别名,包括 volist,resultset,sublist

模版赋值:
$User = D('User')
$list = $User->findAll()
$this->assign('list',$list)

模版定义:
<iterate name="list" id="vo">
{$vo.name}
</iterate>

注意 name 和 id 表示的含义
// 输出 list 的第 5~15 条记录
<iterate name="list" id="vo" offset="5" length='10'>
{$vo.name}
</iterate>

// 输出偶数记录
<iterate name="list" id="vo" mod="2" >
<eq name="mod" value="1">
{$vo.name}
</eq>
</iterate>

// 输出 key
<iterate name="list" id="vo" key="k" >
{$k}.{$vo.name}
</iterate>

//子循环输出
<volist name="list" id="vo">
<sublist name="vo['sub']" id="sub">
{$sub.name}
</sublist>
</volist>

Switch 标签
<switch name="name">
<case value="1">value1</case>
<case value="2">value2</case>
<default />default
</switch>
其 中 name 属性可以使用函数以及系统变量,例如:
<switch name="Think.get.userId|abs">
<case value="1">admin</case>
<default />default
</switch>
也 可以对 case 的 value 属性使用变量,例如:
<switch name="userId">
<case value="$adminId">admin</case>
<case value="$memberId">member</case>
<default />default
</switch>

比较标签
<eq name="name" value="value">value</eq> // name 变量的值等于 value 就输出
<neq name="name" value="value">value</neq> // name 变量的值不等于 value 就输出
<gt name="name" value="5">value</gt> // name 变量的值大于 5 就输出
<egt name="name" value="5">value</egt> // name 变量的值大于等于 5 就输出
<lt name="name" value="5">value</lt> // name 变量的值小于 5 就输出
<elt name="name" value="5">value</elt> // name 变量的值小于等于 5 就输出


//其实上面的所有标签都是 compare 标签的别名
// 其中 type 属性的值就是上面列出的判断标签名称
<compare name="name" value="5" type="eq">value</compare> // name 变量的值等于 5 就输出

If标签
<if condition="$name eq 1 "> value1
<elseif condition="$name eq 2" />value2
<else /> value3
</if>

C操作
操作(动态)配置: 主要用于Action方法里面
获取:
C('配置参数')
设置:
C('配置参数 ',新值)

A操作
快速创建Action对象:
$action = A('User');
等效于
$action = new UserAction();

D操作
快速创建模型数据对象:
$model = D('User');
等效于
$model = new UserModel();

S操作
快速操作缓存方法
获取:
S('name')
设置:
S('name','value');
删 除:
S('name',NULL);

F操作
快速文件数据保存方法
使用方法与S操作一样


L操作
快速操作语言变量
获取:
L('语言变量');
设置:
L('语言变量','值');
如: L('USER_INFO','用户信息'); //设置名称为USER_INFO的语言变量
批量赋值:
$arr['语言变量1'] = '值1';
$arr['语言变量2'] = '值2';
L($arr);


Create PROCEDURE procedure1

(IN parameter1 INTEGER)

BEGIN

DECLARE variable1 CHAR(10);

IF parameter1 = 17 THEN

SET variable1 = 'birds';

ELSE

SET variable1 = 'beasts';

END IF;

Insert INTO table1 VALUES (variable1);

END

ThinkPHP系统常量

THINK_PATH   // ThinkPHP 系统目录
APP_PATH   // 当前项目目录
APP_NAME   // 当前项目名称
MODULE_NAME   //当前模块名称
ACTION_NAME   // 当前操作名称
TMPL_PATH   // 项目模版目录
LIB_PATH   // 项目类库目录
CACHE_PATH   // 项目模版缓存目录

CONFIG_PATH   //项目配置文件目录
LOG_PATH   // 项目日志文件目录
LANG_PATH   // 项目语言文件目录
TEMP_PATH   //项目临时文件目录
PLUGIN_PATH   // 项目插件文件目录
VENDOR_PATH   // 第三方类库目录
DATA_PATH   // 项目数据文件目录
IS_APACHE   // 是否属于 Apache
IS_IIS    //是否属于 IIS
IS_WIN    //是否属于Windows 环境
IS_LINUX   //是否属于 Linux 环境
IS_FREEBSD   //是否属于 FreeBsd 环境
NOW_TIME   // 当前时间戳
MEMORY_LIMIT_ON // 是否有内存使用限制

MEMORY_LIMIT_ON // 是否有内存使用限制
OUTPUT_GZIP_ON   // 是否开启输出压缩
MAGIC_QUOTES_GPC // MAGIC_QUOTES_GPC
THINK_VERSION   //ThinkPHP 版本号
LANG_SET   // 浏览器语言
TEMPLATE_NAME   //当前模版名称
TEMPLATE_PATH   //当前模版路径
__ROOT__   // 网站根目录地址
__APP__   // 当前项目(入口文件)地址
__URL__   // 当前模块地址
__ACTION__   // 当前操作地址
__SELF__   // 当前 URL 地址
TMPL_FILE_NAME   //当前操作的默认模版名(含路径)
WEB_PUBLIC_URL   //网站公共目录
APP_PUBLIC_URL   //项目公共模版目录

预定义常量
WEB_LOG_ERROR=0     // 错误日志类型
WEB_LOG_DEBUG=1 // 调试日志类型
SQL_LOG_DEBUG=2   // SQL 日志类型
SYSTEM_LOG=0   // 系统方式记录日志
MAIL_LOG=1   // 邮件方式记录日志
TCP_LOG=2   // TCP 方式记录日志
FILE_LOG=3   // 文件方式记录日志
DATA_TYPE_OBJ=1 // 对象方式返回
DATA_TYPE_ARRAY=0 // 数组方式返回
URL_COMMON=0   // 普通模式 URL
URL_PATHINFO=1   // PATHINFO URL
URL_REWRITE=2   // REWRITE URL
HAS_ONE=1   // HAS_ONE 关联定义
BELONGS_TO=2   // BELONGS_TO 关联定义
HAS_MANY=3   // HAS_MANY 关联定义
MANY_TO_MANY=4   // MANY_TO_MANY 关联定义
EXISTS_TO_VAILIDATE = 0 // 表单存在字段则验证
MUST_TO_VALIDATE = 1 // 必须验证
VALUE_TO_VAILIDATE = 2 // 表单值不为空则验证

比较好的smarty文章 功能俱全

  • 1 变量调节器
  • 2 capitalize首字母大写
  • 3 count_characters字符计数
  • 4 cat连接字符串
  • 5 count_paragraphs计算段数
  • 6 count_sentences计算句数
  • 7 count_words计算词数
  • 8 date_format格式化日期
  • 9 default默认值
  • 10 escape编码转换
  • 11 indent[缩进]
  • 12 lower小写
  • 13 nl2br换行符替换
  • 14 regex_replace正则替换
  • 15 replace替换
  • 16 spacify插空
  • 17 string_format字符串格式化
  • 18 strip去除(多余空格)
  • 19 strip_tags去除html标签
  • 20 truncate截取
  • 21 upper大写
  • 22 wordwrap 行宽约束

 


变量调节器


变量调节器用于变量,自定义函数和字符串。请使用‘|’符号和调节器名称应用调节器。变量调节器由赋予的参数值决定其行为。参数由‘:’符号分开。 例 5-1.调节器的例子

{* 把标题变为大写 *} 
<h2>{$title|upper}</h2>
 
{* 截取40个字符,用省略号代替后面的文字 *}Topic: {$topic|truncate:40:"..."} 
{* 格式化字符串 *}{"now"|date_format:"%Y/%m/%d"} 
{* 定制函数进行修改 *}{mailto|upper address="me@domain.dom"}

如果你给数组变量应用单值变量的调节,结果是数组的每个值都被调节。如果你只想要调节器用一个值调节整个数组,你必须在调节器名字前加上@符号。例如: {$articleTitle|@count}(这将会在 $articleTitle 数组里输出元素的数目)


capitalize首字母大写


将变量里的所有单词首字大写。

例 5-2.首字大写

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'Police begin campaign to rundown jaywalkers.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|capitalize}

输出结果:

Police begin campaign to rundown jaywalkers.
Police Begin Campaign To Rundown Jaywalkers.

count_characters字符计数


函数作用:计算变量里的字符数 count_characters只有一个参数,它的默认值是false,该参数用于决定是否计算空格字符。

Example 5-3. count_characters

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'Cold Wave Linked to Temperatures.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|count_characters}{$articleTitle|count_characters:true}

OUTPUT输出:

Cold Wave Linked to Temperatures.
2933

cat连接字符串


将cat里的值连接到给定的变量后面. Example 5-4. cat index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "Psychics predict world didn't end");
$smarty->display('index.tpl');

index.tpl:

{$articleTitle|cat:" yesterday."}

输出结果:

Psychics predict world didn't end yesterday.


count_paragraphs计算段数


计算变量里的段落数量。 Example 5-5. count_paragraphs index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "War Dims Hope for Peace. Child's Death Ruins
Couple's Holiday.\n\nMan is Fatally Slain. Death Causes Loneliness, Feeling of Isolation."
); $smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|count_paragraphs}

输出结果:

War Dims Hope for Peace. Child's Death Ruins Couple's Holiday.

Man is Fatally Slain. Death Causes Loneliness, Feeling of Isolation. 2


count_sentences计算句数


计算变量里句子的数量。 Example 5-6. count_sentences index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'Two Soviet Ships Collide - One Dies. Enraged Cow Injures Farmer with Axe.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|count_sentences}

输出结果:

Two Soviet Ships Collide - One Dies. Enraged Cow Injures Farmer with Axe. 2

 


count_words计算词数


计算变量里的词数。

Example 5-7. count_words

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'Dealers Will Hear Car Talk at Noon.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|count_words}

输出结果:

Dealers Will Hear Car Talk at Noon. 7


date_format格式化日期


第一个参数是一个字符串,默认值是"%b %e,%Y",它表示输出日期的格式 第二个参数是一个字符串,默认值是"n/a",它表示输入为空时的默认时间格式。

格式化从函数strftime()获得的时间和日期。 Unix或者mysql等的时间戳记(parsable by strtotime)都可以传递到smarty。 设计者可以使用date_format完全控制日期格式。 如果传给date_format的数据是空的,将使用第二个参数作为时间格式。

Example 5-8. date_format[日期格式]

index.php:

$smarty = new Smarty;
$smarty->assign('yesterday', strtotime('-1 day'));
$smarty->display('index.tpl');

index.tpl:

{$smarty.now|date_format}{$smarty.now|date_format:"%A, %B %e, %Y"}{$smarty.now|date_format:"%H:%M:%S"}{$yesterday|date_format}{$yesterday|date_format:"%A, %B %e, %Y"}{$yesterday|date_format:"%H:%M:%S"}

输出结果:

Feb 6, 2001 Tuesday, February 6, 2001 14:33:00 Feb 5, 2001 Monday, February 5, 2001 14:33:00

Example 5-9. date_format conversion specifiers[日期转换说明]

%a - abbreviated weekday name according to the current locale (根据当地格式输出“星期”缩写格式)

%A - full weekday name according to the current locale (根据当地格式输出“星期”全称格式)

%b - abbreviated month name according to the current locale (根据当地格式输出“月”缩写格式)

%B - full month name according to the current locale (根据当地格式输出“月”全称格式)

%c - preferred date and time representation for the current locale

%C - century number (the year divided by 100 and truncated to an integer, range 00 to 99)

%d - day of the month as a decimal number (range 00 to 31)

%D - same as %m/%d/%y

%e - day of the month as a decimal number, a single digit is preceded by a space (range 1 to 31)

%g - Week-based year within century [00,99]

%G - Week-based year, including the century [0000,9999]

%h - same as %b

%H - hour as a decimal number using a 24-hour clock (range 00 to 23)

%I - hour as a decimal number using a 12-hour clock (range 01 to 12)

%j - day of the year as a decimal number (range 001 to 366)

%k - Hour (24-hour clock) single digits are preceded by a blank. (range 0 to 23)

%l - hour as a decimal number using a 12-hour clock, single digits preceeded by a space (range 1 to 12)

%m - month as a decimal number (range 01 to 12)

%M - minute as a decimal number

%n - newline character

%p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale

%r - time in a.m. and p.m. notation

%R - time in 24 hour notation

%S - second as a decimal number

%t - tab character

%T - current time, equal to %H:%M:%S

%u - weekday as a decimal number [1,7], with 1 representing Monday

%U - week number of the current year as a decimal number, starting with the first Sunday as the first day of the first week

%V - The ISO 8601:1988 week number of the current year as a decimal number, range 01 to 53, where week 1 is the first week that has at least 4 days in the current year, and with Monday as the first day of the week.

%w - day of the week as a decimal, Sunday being 0

%W - week number of the current year as a decimal number, starting with the first Monday as the first day of the first week

%x - preferred date representation for the current locale without the time

%X - preferred time representation for the current locale without the date

%y - year as a decimal number without a century (range 00 to 99)

%Y - year as a decimal number including the century

%Z - time zone or name or abbreviation

%% - a literal `%' character

程序员提示:date_format本质上是php的strftime()函数的一个包装。 当php被编译的时候你可以或多或少的依靠系统的strftime()转换有效的区分符。 可以查看系统手册的有效区分符的全表.


default默认值


为空变量设置一个默认值。 当变量为空或者未分配的时候,将由给定的默认值替代输出。

它的参数是一个字符串,默认值为空。

Example 5-10. default

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'Dealers Will Hear Car Talk at Noon.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle|default:"no title"}{$myTitle|default:"no title"}

输出结果:

Dealers Will Hear Car Talk at Noon. no title

 


escape编码转换


用于html转码,url转码,在没有转码的变量上转换单引号,十六进制转码,十六进制美化,或者javascript转码。默认是html转码。

参数是一些限定的项:“html,htmlall,url,quotes,hex,hexentity,javascript”,只能是这些项中的一个,默认值是html 这个参数决定了使用何种编码格式。

Example 5-11. escape

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "'Stiff Opposition Expected to Casketless Funeral Plan'");
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|escape}{$articleTitle|escape:"html"}{* escapes & " ' < > *}
{$articleTitle|escape:"
htmlall"} {* escapes ALL html entities *}
{$articleTitle|escape:"
url"}
{$articleTitle|escape:"
quotes"}
<a href="
mailto:{$EmailAddress|escape:"hex"}">{$EmailAddress|escape:"hexentity"}</a>

输出结果:

'Stiff Opposition Expected to Casketless Funeral Plan'&#039;Stiff Opposition Expected to Casketless Funeral Plan&#039;&#039;Stiff Opposition Expected to Casketless Funeral Plan&#039;&#039;Stiff Opposition Expected to Casketless Funeral Plan&#039;%27Stiff+Opposition+Expected+to+Casketless+Funeral+Plan%27\'Stiff Opposition Expected to Casketless Funeral Plan\'
<a href="mailto:%62%6f%62%40%6d%65%2e%6e%65%74">&#x62;&#x6f;&#x62;&#x40;&#x6d;&#x65;&#x2e;&#x6e;&#x65;&#x74;</a>

indent[缩进]


在每行缩进字符串,默认是4个字符。 第一个可选参数是数字,默认值是4,你可以指定缩进字符数。 第二个可选参数是字符串,默认值是空格,你可以指定缩进用什么字符代替。

在每行缩进字符串,默认是4个字符。 作为可选参数,你可以指定缩进字符数。 作为第二个可选参数,你可以指定缩进用什么字符代替。

特别提示:使用缩进时如果是在HTML中,则需要使用& n b s p;(空格)来代替缩进,否则没有效果。

Example 5-12. indent

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'NJ judge to rule on nude beach.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle} 
{$articleTitle|indent} 
{$articleTitle|indent:10} 
{$articleTitle|indent:1:"\t"}

输出结果:

NJ judge to rule on nude beach.
Sun or rain expected today, dark tonight.
Statistics show that teen pregnancy drops off significantly after 25.
 
 NJ judge to rule on nude beach.
 Sun or rain expected today, dark tonight.
 Statistics show that teen pregnancy drops off significantly after 25.
 
 NJ judge to rule on nude beach.
 Sun or rain expected today, dark tonight.
 Statistics show that teen pregnancy drops off significantly after 25.
 
	NJ judge to rule on nude beach.
	Sun or rain expected today, dark tonight.
	Statistics show that teen pregnancy drops off significantly after 25.

lower小写


将变量字符串小写

Smarty手册范例 5-13.小写

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'Two Convicts Evade Noose, Jury Hung.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|lower}

输出结果:

Two Convicts Evade Noose, Jury Hung.
two convicts evade noose, jury hung.

nl2br换行符替换


换行符替换成<br />

所有的换行符将被替换成 <br />.功能同PHP中的nl2br()函数一样.

Smarty手册范例 5-14.换行符替换

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "Sun or rain expected\ntoday, dark tonight");
$smarty->display('index.tpl');

index.tpl:

{$articleTitle|nl2br}

输出结果:

Sun or rain expected<br />today, dark tonight

regex_replace正则替换


寻找和替换正则表达式 .

语法请参考Php手册中的preg_replace()函数.

PS:正规表达式一直以来都是程序语言学习的一个难点,所以非程序员建议先跳过本节不必学习。

第一个参数是一个字符串,它是一个替换正则表达式.

第二个参数是一个字符串,它是用来替换的文本字符

这两个参数都是必需的。

Smarty手册范例 5-15.正则替换

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "Infertility unlikely to\nbe passed on, experts say.");
$smarty->display('index.tpl');

index.tpl:

{* replace each carriage return, tab & new line with a space *}{* 使用空格替换每个回车,tab,和换行符 *}{$articleTitle}{$articleTitle|regex_replace:"/[\r\t\n]/":" "}

输出结果:

Infertility unlikely to
 be passed on, experts say.
Infertility unlikely to be passed on, experts say.

replace替换


简单的搜索和替换字符串

Smarty手册范例 5-16.替换

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "Child's Stool Great for Use in Garden.");
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|replace:"Garden":"Vineyard"}{$articleTitle|replace:" ":" "}

输出结果:

Child's Stool Great for Use in Garden.
Child'
s Stool Great for Use in Vineyard. Child's Stool Great for Use in Garden.

 


spacify插空


在字符串的每个字符之间插入空格或者其他的字符(串) 这个函数有一个变量,就是将在两个字符之间插入的字符(串)

Example 5-17. spacify Smarty手册范例 5-17.插空

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'Something Went Wrong in Jet Crash, Experts Say.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|spacify}{$articleTitle|spacify:"^^"}

输出结果:

Something Went Wrong in Jet Crash, Experts Say.
S o m e t h i n g W e n t W r o n g i n J e t C r a s h , E x p e r t s S a y .
S^^o^^m^^e^^t^^h^^i^^n^^g^^ ^^W^^e^^n^^t^^ ^^W^^r^^o^^n^^g^^ ^^i^^n^^ ^^J^^e^^t^^ ^^C^^r^^a^^s^^h^^,^^ ^^E^^x^^p^^e^^r^^t^^s^^ ^^S^^a^^y^^.

string_format字符串格式化


是一种格式化字符串的方法.例如格式化为十进制数等等.使用sprintf语法格式化 这个函数只有一个参数就是使用的格式化方式,这个参数是必需输入的

实例:字符串格式化

index.php:

$smarty = new Smarty;
$smarty->assign('number', 23.5787446);
$smarty->display('index.tpl');

index.tpl:

{$number}{$number|string_format:"%.2f"}{$number|string_format:"%d"}

输出结果:

23.578744623.5824

strip去除(多余空格)


用一个空格或一个给定字符替换所有重复空格,换行和制表符.

Smarty手册范例 5-19.去除(多余空格)

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "Grandmother of\neight makes\t hole in one.");
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|strip}{$articleTitle|strip:"&nbsp;"}

输出结果:

Grandmother of
eight makes hole in one.
Grandmother of eight makes hole in one.
Grandmother&nbsp;of&nbsp;eight&nbsp;makes&nbsp;hole&nbsp;in&nbsp;one.

strip_tags去除html标签


去除"<"和">"标签,包括在"<"和">"之间的任何内容.

Smarty手册范例 5-20.去除Html标签

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "Blind Woman Gets <font face=\"helvetica\">New Kidney</font> from Dad she Hasn't Seen in <b>years</b>.");
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|strip_tags}

输出结果:

Blind Woman Gets <font face="helvetica">New Kidney</font> from Dad she Hasn't Seen in <b>years</b>.
Blind Woman Gets New Kidney from Dad she Hasn'
t Seen in years.

 


truncate截取


第一个变量是一个整数,它表示截取字符的数量,默认值是80 第二个变量是一个字串,它表示截取后追加在截取词后面的字符串,默认值是"…" 第二个变量是一个逻辑值,它表示是截取到词的边界(假)还是精确到字符(真),默认值是false

从字符串开始处截取某长度的字符.默认是80个. 你也可以指定第二个参数作为追加在截取字符串后面的文本字串.该追加字串被计算在截取长度中。 默认情况下,smarty会截取到一个词的末尾。 如果你想要精确的截取多少个字符,把第三个参数改为"true"

例5-21.截取

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', 'Two Sisters Reunite after Eighteen Years at Checkout Counter.');
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|truncate}{$articleTitle|truncate:30}{$articleTitle|truncate:30:""}{$articleTitle|truncate:30:"---"}{$articleTitle|truncate:30:"":true}{$articleTitle|truncate:30:"...":true}

输出结果:

Two Sisters Reunite after Eighteen Years at Checkout Counter.
Two Sisters Reunite after Eighteen Years at Checkout Counter.
Two Sisters Reunite after...
Two Sisters Reunite after
Two Sisters Reunite after---
Two Sisters Reunite after Eigh
Two Sisters Reunite after E...

upper大写


将变量改为大写

Smarty手册范例 5-22.大写

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "If Strike isn't Settled Quickly it may Last a While.");
$smarty->display('index.tpl');

index.tpl:

{$articleTitle}{$articleTitle|upper}

输出结果:

If Strike isn't Settled Quickly it may Last a While.
IF STRIKE ISN'
T SETTLED QUICKLY IT MAY LAST A WHILE.

wordwrap 行宽约束


第一个参数是一个整数,默认值是80,它决定了句子的宽度 第二个参数是一个字串,默认值是\n,它表示用回车符来约束 第三个参数是个逻辑值,默认值是false,它表示是约束到词的边界(假)还是精确到字符(真)


可以指定段落的宽度(也就是多少个字符一行,超过这个字符数换行).默认80. 第二个参数可选,可以指定在约束点使用什么字符(默认是换行符\n). 默认情况下smarty将截取到词尾,如果想精确到设定长度的字符,请将第三个参数设为ture

例 5-23.行宽约束

index.php:

$smarty = new Smarty;
$smarty->assign('articleTitle', "Blind woman gets new kidney from dad she hasn't seen in years.");
$smarty->display('index.tpl');

index.tpl:

{$articleTitle} 
{$articleTitle|wordwrap:30} 
{$articleTitle|wordwrap:20}{$articleTitle|wordwrap:30:"<br>\n"} 
{$articleTitle|wordwrap:30:"\n":true}

结果显示:

Blind woman gets new kidney from dad she hasn't seen in years.
 
Blind woman gets new kidney
from dad she hasn'
t seen in years.   Blind woman gets newkidney from dad she hasn't seen in
years.
 
Blind woman gets new kidney<br>
from dad she hasn'
t seen in years.   Blind woman gets new kidney fr om dad she hasn't seen in year
s.

PHP服务器变量$_SERVER详解

 服务器变量 $_SERVER 详解:

1、$_SESSION['PHP_SELF'] -- 获取当前正在执行脚本的文件名

2、$_SERVER['SERVER_PROTOCOL'] -- 请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。

3、$_SERVER['REQUEST_TIME'] -- 请求开始时的时间戳。从 PHP 5.1.0 起有效。和time函数效果一样。

4、$_SERVER['argv'] -- 传递给该脚本的参数。我试了下,get方法可以得到$_SERVER['argv'][0];post方法无法给他赋值。

5、$_SERVER['SERVER_NAME'] -- 返回当前主机名。

6、$_SERVER['SERVER_SOFTWARE'] -- 服务器标识的字串,在响应请求时的头信息中给出。 如Microsoft-IIS/6.0

7、$_SERVER['REQUEST_METHOD'] -- 访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT”。

8、$_SERVER['QUERY_STRING'] -- 查询(query)的字符串(URL 中第一个问号 ? 之后的内容)。

9、$_SERVER['DOCUMENT_ROOT'] -- 当前运行脚本所在的文档根目录。在服务器配置文件中定义。 如E:\server

10、$_SERVER['HTTP_ACCEPT'] -- 当前请求的 Accept: 头信息的内容。

11、$_SERVER['HTTP_ACCEPT_CHARSET'] -- 当前请求的 Accept-Charset: 头信息的内容。例如:“iso-8859-1,*,utf-8”。

12、$_SERVER['HTTP_ACCEPT_ENCODING'] -- 当前请求的 Accept-Encoding: 头信息的内容。例如:“gzip”。

13、$_SERVER['HTTP_ACCEPT_LANGUAGE'] -- 当前请求的 Accept-Language: 头信息的内容。例如:“en”。

14、$_SERVER['HTTP_CONNECTION'] -- 当前请求的 Connection: 头信息的内容。例如:“Keep-Alive”。

15、$_SERVER['HTTP_HOST'] -- 当前请求的 Host: 头信息的内容。

16、$_SERVER['HTTP_REFERER'] -- 链接到当前页面的前一页面的 URL 地址。

17、$_SERVER['HTTP_USER_AGENT'] -- 返回用户使用的浏览器信息。也可以使用 get_browser() 得到此信息。

18、$_SERVER['HTTPS'] -- 如果通过https访问,则被设为一个非空的值,否则返回off.

19、$_SERVER['REMOTE_ADDR'] -- 正在浏览当前页面用户的 IP 地址。

20、$_SERVER['REMOTE_HOST'] -- 正在浏览当前页面用户的主机名。反向域名解析基于该用户的 REMOTE_ADDR。如本地测试返回127.0.0.1

21、$_SERVER['REMOTE_PORT'] -- 用户连接到服务器时所使用的端口。我在本机测试没通过,不知道什么原因。

22、$_SERVER['SCRIPT_FILENAME'] -- 当前执行脚本的绝对路径名。如返回E:\server\index.php

23、$_SERVER['SERVER_ADMIN'] -- 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值

24、$_SERVER['SERVER_PORT'] -- 服务器所使用的端口。默认为“80”。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。

25、$_SERVER['SERVER_SIGNATURE'] -- 包含服务器版本和虚拟主机名的字符串。

26、$_SERVER['PATH_TRANSLATED'] -- 当前脚本所在文件系统(不是文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。 Apache 2 用 户可以使用 httpd.conf 中的 AcceptPathInfo On 来定义 PATH_INFO。

27、$_SERVER['SCRIPT_NAME'] -- 包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 包含当前文件的绝对路径和文件名(例如包含文件)。

28、$_SERVER['REQUEST_URI'] -- 访问此页面所需的 URI。例如,“/index.html”。

29、$_SERVER['PHP_AUTH_DIGEST'] -- 当作为 Apache 模块运行时,进行 HTTP Digest 认证的过程中,此变量被设置成客户端发送的“Authorization”HTTP 头内容(以便作进一步的认证操作)。

30、$_SERVER['PHP_AUTH_USER']-- 当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。

31、$_SERVER['PHP_AUTH_PW'] -- 当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。

32、$_SERVER['AUTH_TYPE']--当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。

PHP100编程安全性小结

  规则 1:绝不要信任外部数据或输入

  关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

  对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。

  规则 2:禁用那些使安全性难以实施的 PHP 设置

  已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GET 或 POST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

  要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。

  规则 3:如果不能理解它,就不能保护它

  一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

  规则 4:“纵深防御” 是新的法宝

  即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

  纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

PHP关于引用的理解

php引用(&)详解 php的引用(就是在变量或者函数、对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容在内存中存放的地址 变量的引用 PHP 的引用允许你用两个变量来指向同一个内容 [php] <? $a="ABC"; $b =&$a; echo $a;//这里输出:ABC echo $b;//这里输出:ABC $b="EFG"; echo $a;//这里$a的值变为EFG 所以输出EFG echo $b;//这里输出EFG ?> [/php] 函数的传址调用 传址调用我就不多说了 下面直接给出代码 [php] function test(&$a) { $a=$a+100; } $b=1; echo $b;//输出1 test($b); //这里$b传递给函数的其实是$b的变量内容所处的内存地址,通过在函数里改变$a的值 就可以改变$b的值了 echo "
"; echo $b;//输出101 [/php] 要注意的是,在这里test(1);的话就会出错,原因自己去想 函数的引用返回 先看代码 [php] function &test() { static $b=0;//申明一个静态变量 $b=$b+1; echo $b; return $b; } $a=test();//这条语句会输出 $b的值 为1 $a=5; $a=test();//这条语句会输出 $b的值 为2 $a=&test();//这条语句会输出 $b的值 为3 $a=5; $a=test();//这条语句会输出 $b的值 为6 [/php] 下面解释下:  通过这种方式$a=test();得到的其实不是函数的引用返回,这跟普通的函数调用没有区别 至于原因: 这是PHP的规定 PHP规定通过$a=&test(); 方式得到的才是函数的引用返回 至于什么是引用返回呢(PHP手册上说:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。) 这句狗屁话 害我半天没看懂 用上面的例子来解释就是 $a=test()方式调用函数,只是将函数的值赋给$a而已, 而$a做任何改变 都不会影响到函数中的$b 而通过$a=&test()方式调用函数呢, 他的作用是 将return $b中的 $b变量的内存地址与$a变量的内存地址 指向了同一个地方 即产生了相当于这样的效果($a=&b;) 所以改变$a的值 也同时改变了$b的值 所以在执行了 $a=&test(); $a=5; 以后,$b的值变为了5 这里是为了让大家理解函数的引用返回才使用静态变量的,其实函数的引用返回多用在对象中 对象的引用 [php] <? class a{ var $abc="ABC"; } $b=new a; $c=$b; echo $b->abc;//这里输出ABC echo $c->abc;//这里输出ABC $b->abc="DEF"; echo $c->abc;//这里输出DEF ?> [/php] 以上代码是在PHP5中的运行效果 在PHP5中 对象的复制 是通过引用来实现的。上列中$b=new a; $c=$b; 其实等效于$b=new a; $c=&$b; PHP5中默认就是通过引用来调用对象, 但有时你可能想建立一个对象的副本,并希望原来的对象的改变不影响到副本 . 为了这样的目的,PHP定义了一个特殊的方法,称为__clone. 引用的作用 如果程序比较大,引用同一个对象的变量比较多,并且希望用完该对象后手工清除它,个人建议用 "&" 方式,然后用$var=null的方式清除. 其它时候还是用php5的默认方式吧. 另外, php5中对于大数组的传递,建议用 "&" 方式, 毕竟节省内存空间使用。 取消引用 当你 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。例如: <?php $a = 1; $b =& $a; unset ($a); ?> 不会 unset $b,只是 $a。 global 引用 当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用。也就是说和这样做是相同的: <?php $var =& $GLOBALS["var"]; ?> 这意味着,例如,unset $var 不会 unset 全局变量。 $this 在一个对象的方法中,$this 永远是调用它的对象的引用。 //下面再来个小插曲 php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。 通俗的讲 1:如果有下面的代码 [php] $a="ABC"; $b=$a; [/php] 其实此时 $a与$b都是指向同一内存地址 而并不是$a与$b占用不同的内存 2:如果在上面的代码基础上再加上如下代码 [php] $a="EFG"; [/php] 由于$a与$b所指向的内存的数据要重新写一次了,此时Zend核心会自动判断 自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储 一个例子 <?php $arr = array(1, 2, 3, 4); foreach ($arr as &$value) { $value = $value * 2; } // $arr is now array(2, 4, 6, 8) ?>

标签: php, 函数, 变量, 引用