分类存档: 程序开发 - 第2页

Zend Translate的使用和设置

Zend Translate的功能不错, 我们使用gettext格式作为我们翻译文件的标准格式,使用POEditor维护翻译文件,处理后的gettext文件是二进制的mo文件. 我们使用ZF的根据目录名(LOCALE_DIRECTORY)自动搜索相关译文功能,同时使用根据mo文件更新的cache提高速度,为了设置translate功能,我们在bootstrap文件有如下代码
$cache = Zend_Cache::factory('Page','File',$frontendOptions,$backendOptions);
Zend_Translate::setCache($cache);
$translate = new Zend_Translate('gettext','../data/locales/','zh',array(
    'scan' =>Zend_Translate::LOCALE_DIRECTORY
));
$translate->setLocale('auto');
Zend_Registry::set('Zend_Translate', $adapter);
Zend_Form::setDefaultTranslator($translate);

注意:在保存到 Zend_Registry 中时,键值必须是 Zend_Translate,否则,得不到应有的结果。

其中,‘scan’ =>Zend_Translate::LOCALE_DIRECTORY设定ZF在指定目录下搜索翻译mo文件。我们的目录结构为:
application
...
data
  ...
  locales
    en
    de
    fr
    zh
...

在ZF的Document中有一个Example,要求设置’auto’格式:
$translate = new Zend_Translate('gettext','path','auto',array('scan' =>Zend_Translate::LOCALE_DIRECTORY));

但是事实上根据我在ZF1.52, 1.6, 1.61中测试,这个代码是有bug的, ‘auto’并不能正确将用户浏览器语言设置为当前语言,而是将最后一个读到的文件设置为默认Locale, 这点从ZF1.61的代码中Zend_Translate_Adapter::addTranslation函数中可以看到。

我们是怎么解决的呢,很简单,第一次读取时设置语言为’zh’, 然后立即设定默认locale为’auto’

VN:F [1.9.14_1148]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)

关于BOM头

要命的BOM头让我吃了两次亏,每次都是莫名奇妙地花了1,2天才找出问题。
第一次是:写ZF的errorControler设置404返回值的时候报错:
Cannot modify header information - headers already sent
检查了那个有名的ZF最后一个结束符不写的问题和setRawHeader的代码,都找不出症结所在,后来发现是BOM头捣鬼。
今天又碰到这个问题,导入系统一个excel文件,老有错,仔细检查是第一行含有bom头,所以数据老是读错,害我花了半天的时间找问题。

在Windows下用记事本之类的程序将文本文件保存为UTF-8格式时,记事本会在文件头前面加上几个不可见的字符(EF BB BF),就是所谓的BOM(Byte order Mark)。

4/5会视BOM为一般字符输出(这是一个不可见字符),因此会出现这个header already sent的问题。应该说这是一个php的bug(22108, 42312),可喜的是,php6宣传已经没有这个问题,而在php4/5下,有两个方法可以解决这一问题:
方法一,可以在保存文件的时候设置不使用BOM头格式的UTF8文件。
dreamweaver设置如下:

UltraEdit可以设置(Configuration-> File Handling -> Save -> Write UTF-8 BOM header),
也可以直接修改C:\Windows\UEdit32.ini,增加以下两行设置
Write UTF-8 BOM=0
Write UTF-8 BOM NF=0

此外HTML代码中的codepage及charset也必须要设定,以保证编码方式正确。

方法二,以上方式可以解决自己写的代码,却不能解决用户上传的文件。这种情况下,需要在服务器端判断文件头,并截取相应的三个字符(0xEF 0xBB 0xBF),以下代码是FCKeditor的一段代码,由于考虑到可能要处理的文件较大,所以将传值函数改成传递引用:
//strip UTF8 BOM if any
function StripUtf8Bom( &$data ){
  if ( substr( $data, 0, 3 ) == "\xEF\xBB\xBF" ){
   $data=substr_replace( $data, '', 0, 3 ) ;
   return TRUE;
  }
  return FALSE;
}

关于为何能提高性能,见风雪之隅的博客介绍的php传递引用的实现

VN:F [1.9.14_1148]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.14_1148]
Rating: +1 (from 1 vote)

XAMPP设置和使用

我们使用XAMPP作为本地开发环境,主要的原因还是非常方便地安装了我们所需要的开发环境,几乎是不需要什么设置,目前支持windows,linux,macOS和solaris,几乎涵盖了绝大多数主流开发者使用的操作系统。下面介绍windowsXP下的设置,vista的设置类似。
首先在XAMPP官方网站下载XAMPP,下载后在D盘根目录创建XAMPP目录,将解压缩后的xampp拷贝进去,执行setup-xampp.bat即可。

要启动apache,可以运行xampp目录喜爱的xampp-control.exe,也可以执行xampp-start.exe,启动apache和mysql。

配置为系统服务,使得系统重启之后自动运行。在 NT4、2000 和 XP 平台中将特定的服务器配置为系统服务。可以以下脚本:

安装 服务器为系统服务:.\xampp\\apache_installservice.bat
卸载 Apache 服务器的系统服务:.\xampp\apache\apache_uninstallservice.bat
安装 MySQL 服务器为系统服务:.\xampp\mysql\mysql_installservice.bat
卸载 MySQL 服务器的系统服务:.\xampp\mysql\mysql_uninstallservice.bat
安装及卸载 FileZilla FTP 服务器为系统服务:.\xampp\filezilla_setup.bat
Mercury 邮件服务器:目前还不能配置为系统服务!

PEAR的设置:

/xampp//go-pear,一直回车,到设置php.ini时注意使用/xampp/apache/bin/.in而不是/xampp//php.ini回车,就安装好pear了
现在先检查下配置:
d:/xampp/php/pear config-show

然后按需要安装phpunit和一些重要的模块
d:/xampp/php/pear channel-discover pear.phpunit.de
d:/xampp/php/pear install log
d:/xampp/php/pecl install pdo_sqlite
d:/xampp/php/pear install xdebug
d:/xampp/php/pear install php/PHPUnit
d:/xampp/php/pear config

VN:F [1.9.14_1148]
Rating: 1.0/10 (1 vote cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)

Zend Framework的项目目录结构

参考ZF1.6版本之前建议的通用目录结构 ,或许你能找到你现在的代码所使用的目录结构。目前我们开发使用的文件结构
框架遵循Zend Framework 1.6 Proposal Project Structure如下:

<project name>/
  application/
    apis/
    config/
    controllers/
        helpers/
    layouts/
        filters/
        helpers/
        scripts/
    models/
    modules/
    views/
        filters/
        helpers/
        scripts/
    bootstrap.
  data/
    cache/
    indexes/
    locales/
    logs/
    sessions/
    uploads/
  docs/
  library/
  public/
    /
    js/
    images/
    .htaccess
    index.
  scripts/
    jobs/
    build/
  temp/
  tests/

2009/7/30更新:ZF1.8的推荐项目目录结构:

根据项目的复杂度不同和需要不同,可以有不同的目录构造,Zend Framework所推荐的目录结构如这篇proposal所示。我所使用的目录结构图和ZF的规范相同,可以用zend tool直接生成:

dev:~# cd /var/www/jefflei
dev:~# zf create project .
Creating project at /var/www/jefflei

目录结构大致如示意图所示,因为比较懒,借用了别人的结构图。我们使用的有如下几点不同:

1. .htaccess, index.php是放在public目录下的,这样方便将document root设置到public目录下,增强安全性。

2. library。如果不是需要同时在多个项目中使用不同版本的Zend Framework类库,建议将ZendFramework类库放在项目目录的外面,这样减少主项目的size。

3. Modules目录下通常是application目录结构的迭代,比如:

`-- application
|  `-- controllers
|  `-- models
|  `-- views
|  `-- modules
|  |   `-- foo
|  |       `-- controllers
|  |       `-- models
|  |       `-- views
|  |       `-- Bootstrap.php  ⇐ class Foo_Bootstrap extends Zend_Application_Module_Bootstrap
|  `-- Bootstrap.php ⇐ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
`-- public

以上部分也可以用Zend Tool来生成:

dev:~# zf create module foo
Creating the following module and artifacts:
/var/www/jefflei/application/modules/foo/controllers
/var/www/jefflei/application/modules/foo/models
/var/www/jefflei/application/modules/foo/views
/var/www/jefflei/application/modules/foo/views/scripts
/var/www/jefflei/application/modules/foo/views/helpers
/var/www/jefflei/application/modules/foo/views/filters
Updating project profile '/var/www/jefflei/.zfproject.xml'

dev:~# zf create controller index index-action-included=1 foo

另外一些大型项目一般都会另外单独建立extension目录,运行项目之间共享common的代码,大致结构如下:

;;;;extensions?;;;;
;   extensions/
;       <extension_name>
;           application/
;               configs/
;                   ownroute.ini
;                   extension.ini
;               controllers/
;                   helpers/
;               views/
;                   filters/
;                   helpers/
;                   scripts/
;               layouts/
;                   filters/
;                   helpers/
;                   scripts/
;               models/
;           docs/
;           data/
;               indexes/
;               locales/
;               logs/
;               uploads/
;           library/
;           override_public/
;               scripts/
;               styles/
;               images/
;;;;extensions?;;;;
VN:F [1.9.14_1148]
Rating: 10.0/10 (2 votes cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)

Zend Framework的设置(apache)

  1. 编辑C:WINDOWSSystem32driversetchosts文件,增加一个域,如127.0.0.1  audit.local
  2. 修改apache的configure文件,在xampp环境下就是在d:/xampp//conf目录下,首先编辑httpd.conf,开启rewrite模块:将这行的注释去掉:LoadModule rewrite_module modules/mod_rewrite.so然后编辑extra/http-vhosts.conf文件,增加如下行:
    <VirtualHost *:80>
        DocumentRoot "D:/xampp/htdocs/"
        ServerName localhost
        ErrorLog logs/localhost.error_log
        CustomLog logs/localhost.access_log common
    </VirtualHost>
    <VirtualHost *:80>
        DocumentRoot "D:/xampp/audit/public/"
        ServerName audit.local
        ErrorLog logs/audit.error_log
        CustomLog logs/audit.access_log common
       
        RewriteEngine off
        <Location />
            RewriteEngine on
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule !.(js|ico|gif|jpg|jpeg|pdf|png|)$ /index.
        </Location>
        <directory "D:/xampp/audit/public">
    #Allow server side include,cgi, disable directory index
          Options FollowSymLinks Includes ExecCGI
          Order allow,deny
          Allow from all
        </directory>
    </VirtualHost>
    然后去掉NameVirtualHost这行的注释,重新启动apache,就可以开始使用了更多关于apache rewrite rule的写法和说明。
    如果在nginx服务器上,参考nginx下的zend framework的设置
  3. 下载zend framework并安装到php/lib目录下
  4. 建立项目的文件目录,你可以用最基本的zend framework quick start中推荐的结构,也可以直接使用我们项目使用的ZF1.6标准目录结构

此文发布时ZF的版本为1.6.1

VN:F [1.9.14_1148]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)

CSS A连接写法快速记忆

大家都知道CSS的使用繁复著称,而且还有各种对浏览器的兼容和对浏览器bug的容错处理。今天看到一个挺有趣的CSS记忆方法值得写一下:

连接属性:LoVe, HAte

LoVe, HAte 是 CSS Link 属性在说明时常用快速记忆方法. 主要是 a: 在写的时候, 要依照 a:link, a:visited, a:hover, a:active(LVHA)的顺序写, 不然某些属性就不起作用

VN:F [1.9.14_1148]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)

XSS攻击简介

XSS(Cross Site Script)跨站脚本攻击。是指攻击者向被攻击Web 页面里插入恶意html代码,当用户浏览该页之时,嵌入其中的HTML代码会被执行,从而达到攻击的特殊目的。XSS和CSRF(Cross site request forgery)合称Web 杀手组合。XSS攻击的危害有:
1、盗取各类用户帐号,如机器登录帐号、网银帐号、各类管理员帐号
2、控制企业信息,包括读取、篡改、增删企业敏感数据的能力
3、非法转账和网站挂马
4、控制受害者机器(俗称肉鸡),通常是向其它网站发起攻击或强制发送电子邮件等

攻击Yahoo Mail 的Yamanner 蠕虫是一个著名的XSS 攻击实例。早期Yahoo Mail 系统有一个漏洞,当用户在web 界面查收邮件时有可能执行到信件内的javascript 代码。利用这个漏洞, XSS攻击者让用户运行了含有病毒的js代码。并且Yahoo Mail 系统使用了Ajax技术,这样病毒javascript 可以的向Yahoo Mail 系统发起ajax 请求,从而得到用户的地址簿,并发送病毒给他人。

常见XSS 攻击手法按攻击来源分为两类:一类是来自内部的攻击,这一类攻击手法类似于SQL Injection, 利用WEB程序没有对用户输入作充分的检查和过滤.攻击者通过提交特殊的字符串使得XSS跨站页面直接存在于被攻击站点上,这个字符串被称为XSS跨站语 句。Yamanner 就是XSS内部攻击的一例。

另一类则是来来自外部的攻击,主要指的自己构造XSS 跨站漏洞网页或者寻找非目标机以外的有跨站漏洞的网页。如当我们要渗透一个站点,我们自己构造一个跨站网页放在自己的服务器上,然后通过结合其它技术,如 社会工程学等,欺骗目标服务器的管理员打开。这一类攻击的威胁相对较低,至少ajax 要发起跨站调用是非常困难的。

XSS漏洞按照攻击利用手法的不同,有以下三种类型:

类型A,本地利用漏洞存在于页面中客户端脚本自身。其攻击过程如下:

Alice给Bob发送一个恶意构造了Web的URL。

Bob点击并查看了这个URL。

恶意页面中的JavaScript打开一个具有漏洞的HTML页面并将其安装在Bob电脑上。

具有漏洞的HTML页面包含了在Bob电脑本地域执行的JavaScript。

Alice的恶意脚本可以在Bob的电脑上执行Bob所持有的权限下的命令。

类型B,反射式漏洞反射式XSS漏洞和类型A有些类似,不同的是Web客户端使用Server端脚本生成页面为用户提供数据时,如果未经验证的用户数据被包含在页面中而未经HTML实体编码,客户端代码便能够注入到动态页面中。其攻击过程如下:

Alice经常浏览某个网站,此网站为Bob所拥有。Bob的站点运行Alice使用用户名/密码进行登录,并存储敏感信息(比如银行帐户信息)。

Charly发现Bob的站点包含反射性的XSS漏洞。

Charly编写一个利用漏洞的URL,并将其冒充为来自Bob的邮件发送给Alice。

Alice在登录到Bob的站点后,浏览Charly提供的URL。

嵌入到URL中的恶意脚本在Alice的浏览器中执行,就像它直接来自Bob的服务器一样。此脚本盗窃敏感信息(授权、信用卡、帐号信息等)然后在Alice完全不知情的情况下将这些信息发送到Charly的Web站点。

类型C,存储式漏洞,该类型是应用最为广泛而且有可能影响到Web服务器自身安全的漏洞,骇客将攻击脚本上传到Web服务器上,使得所有访问该页面的用户都面临信息泄漏的可能,其中也包括了Web服务器的管理员。其攻击过程如下:

Bob拥有一个Web站点,该站点允许用户发布信息/浏览已发布的信息。

Charly注意到Bob的站点具有类型C的XXS漏洞。

Charly发布一个热点信息,吸引其它用户纷纷阅读。

Bob或者是任何的其他人如Alice浏览该信息,其会话cookies或者其它信息将被Charly盗走。

VN:F [1.9.14_1148]
Rating: 8.5/10 (2 votes cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)

PHP中文截字、断字2个函数介绍

在写页面的时候常会遇到 30 个字要截字, 超过 30 字加 “…”, 未满 30 字不加.. 等等问题. 之前用 substr 的写法如下:

$string = strip_tags($string); // 先清掉 html tag, 以免 html tag 被破坏
$string = mb_substr($string, 0, 80, 'UTF-8');
$string .= (mb_strlen($string, 'UTF-8') > 80)?'...':'';

有很方便的函数mb_strimwidth可以直接达到此功能.

$string = strip_tags($string);
$string = mb_strimwidth($string, 0, 80, '...', 'UTF-8');

在UTF-8 情况下算字长用 strlen 或 mb_strlen 都不是很准确, 所以可以用另一个方法mb_strwidth, 算字的宽度:

echo mb_strwidth($string, 'UTF-8'); // 算字长

现在我们回过来看mb_strimwidth的解决方法,如果最后被截断的是2个空格,那么格式就会变得很丑陋,这是我们可以用以下方法:

rtrim(mb_strimwidth($string, 0, 24))."..."

今天看了一篇不错的文章:用Tidy库处理用户输入的中文http://nukq.malmam.com/archives/14

VN:F [1.9.14_1148]
Rating: 6.5/10 (2 votes cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)

CSS入门

番茄’s blog 不错的css初学者教程, 前提是有一点点HTML代码基础: )

css在线手册

The visual design of Web 2.0 web2.0 流行用色

CSS2盒模型2中的盒模型是关系到设计中排版定位的关键,任何一个选择符都遵循盒模型规范,例如、、……盒模型包含
(外补丁)margin,(背景颜色)background-color,(背景图片)background-image,(内补丁)padding ,(内容)content,(边框)border。
下图是CSS盒模型的示意图
css盒模型css三维模型需要说明的是:IE和Mozilla浏览器对盒模型的解释不一致,造成我们定位上的困难,主要差别是:

 

IE计算2个div之间的距离时候,会把1px的border计算在内,而mozilla没有;
设定div的宽度后,如果给padding加一个值,IE 5.x会在宽度内减去这个值,而IE 6 & M ozilla会在宽度基础上加上这个值。

css定位元素的使用:

1. position:static|无定位:position:static是所有元素定位的默认值, 一般不用注明,除非有需要取消继承的别的定位
2. position:relative|相对定位: 使用position:relative,就需要top,bottom,left,right4个属性来配合,确定元素的位置。

如,如果要让div-1层向下移动20px,左移40px:
#div-1 {position:relative;top:20px;left:40px;}
3. position:absolute|绝对定位: 使用position:absolute;,能够很准确的将元素移动到你想要的位置.

4. position:relative + position:absolute|绝对定位+相对定位
  如果给父元素(div-1)定义为position:relative;子元素(div-1a)定义为position:absolute,那么子元素(div-1a)的位置将相对于父元素(div-1),而不是整个页面

5 .float|浮动对齐
  使用float定位一个元素有float:left;&float:right;两种值。这种定位只能在水平坐标定位,不能在垂直坐标定位。而且让下面的元素浮动环绕在它的左边或者右边。

7.clear float|清除浮动
  如果你不想让使用了float元素的下面的元素浮动环绕在它的周围,那么你就使用clear,clear有三个值,clear:left;(清除左浮动),clear:right;(清除右浮动),clear:both;(清除所有浮动)。

VN:F [1.9.14_1148]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)

PHP多字节字符串处理函数mbstring函数库

PHP内置的字符串长度函数strlen无法正确处理中文字符串,它得到的只是字符串所占的字节数。对于GB2312的中文编码,strlen得到的值是汉字个数的2倍,而对于UTF-8编码的中文,就是1~3倍的差异了。

采用mb_strlen函数可以较好地解决这个问题。mb_strlen的用法和strlen类似,只不过它有第二个可选参数用于指定字符编码。例如得到UTF-8的字符串$str长度,可以用mb_strlen($str,’UTF-8′)。如果省略第二个参数,则会使用PHP的内部编码。内部编码可以通过mb_internal_encoding()函数得到,设置有两种方式:
1. 在php.ini中设置mbstring.internal_encoding = UTF-8
2. 调用mb_internal_encoding(“GBK”)

除了mb_strlen,还有很多切割函数,其中mb_substr是按字来切分字符,而mb_strcut是按字节来切分字符,但是都不会产生半个字符的现象。而且从函数切割对长度的作用也不同,mb_strcut的切割条件是小于strlen, mb_substr是等于strlen,看下面的例子,

$str = '我是一串比较长的中文-www.jefflei.com';
echo "mb_substr:" . mb_substr($str, 0, 6, 'utf-8');
echo "
";
echo "mb_strcut:" . mb_strcut($str, 0, 6, 'utf-8');
?>

输出如下:

mb_substr:我是一串比较
mb_strcut:我是

需要注意的是,mb_strlen并不是PHP核心函数,使用前需要确保在php编译模块时加入mbstring的支持:
(1)编译时使用–enable-mbstring
(2)修改/usr/local/lib/.inc
default_charset = “zh-cn”
mbstring.language = zh-cn
mbstring.internal_encoding =zh-cn

mbstring类库内容比较多,还包括mb_ send_ mail 之类的email处理函数等

VN:F [1.9.14_1148]
Rating: 9.0/10 (3 votes cast)
VN:F [1.9.14_1148]
Rating: 0 (from 0 votes)
Page 2 of 212