存档

文章标签 ‘PHP学习’

PHP一个诡异的情况处理办法

2008年9月5日

最近爱上了Ubuntu,一直在Ubuntu下面工作。
辛苦了几天,终于将YoYo的事情做了七七八八了,发给了他之后觉得不放心,回到Windows下面准备再看一下,结果,诡异的事情就发生了。
在Ubuntu下正常无比的index.php,到了Windows下面,赫然出现

Parse error: syntax error, unexpected $end

怎一个郁闷了得~
搞了半天没有搞定,无奈Google百度一起上,最终找到了原因。
其实也是我太大意了,没有仔细去看这段话的真正的意思,其实这句话的意思翻译过来就是“语法错误:有一个意料之外的文件结尾”,也就是用PHP语言来说就是多了一个”}”
但是用Aptana打开却没有任何的错误,于是我就绕路了,觉得是文件损坏,弄了半天没有搞定。
其实这个提示告诉我们,现在没有和”}”对应的PHP开头!!
郁闷~~
这种事情告诉我们以后看到错误,最先从字面意思去理解是很重要的~~
说一下解决办法吧,全文搜索,将不标准的PHP开头,比如”

PHP学习 , ,

决定用Symfony

2008年6月19日

一直徘徊在Symfony和Zend FrameWork之间~
其实我对于ZF的了解很早,当时刚刚才开始做PHP,了解了一些关于框架的东西~~当时跳入我眼帘的就有ZF~
可惜当时对于框架压根就没有什么了解,觉得这个东西乱七八糟的,不好用~囧~~
最终被我选做第一个学习的框架是ThinkPHP,觉得这个框架的思想和我对于框架的理解基本上完全一样,同样的AR,同样的重惯例轻配置,同样的以function来区分每个操作!!欧耶!!
这个就是我要用的框架!
慢慢看到ZF到了1.0正式版,现在又到了1.5.2~
同时,Symfony也让我看到了~
与我而言,比较偏重于Symfony,而一个好友(老沙)却更加倾向于ZF。处于对老沙的尊重(技术大牛哦),我就都看了一下~
最终我还是决定用Symfony~~
ZF真的太让我失望了!!为了OO而去OO,原先PHP本身就似乎不支持MVC,所有框架都在解决MVC的问题。可惜ZF在这点做的实在是太让人失望了!!完全不像一个框架,而更加接近于PEAR,以类库的性质将PHP组合成MVC,中间穿插一些Helper来辅助操作。个人完全不能接受这样子的框架。与其使用ZF,我更加倾向于使用ZF中的一些类库而使用其他的框架。
Symfony确实能称得上PHP中唯一一个能和J2EE争锋的重量级框架,虽然是在模仿RoR,但是对于PHP的MVC的理解也是让人眼前一亮(感觉PHP中类RoR框架好像都差不多)。不过Symfony的缺点也是显而易见的,既然能和J2EE抗衡,那么复杂度可见一斑,YAML的配置方式以及层层目录让人看得不禁觉得心里发冷。好在有命令行来辅助操作,让人松了一口气~
总的而言,并非ZF不够优秀,至少我认为里面那么多类库能写出来绝对非一般框架能做到。但是ZF实在是和PHP的轻量级注重敏捷的开发模式有些背道而驰~所以,我只能对ZF说ByeBye,至少是暂时的ByeBye~
Symfony,我来了!!

PHP学习

今天干龌龊事了

2008年5月4日

今天我龌龊了~~
不要误解,这个龌龊不是干了啥见不得人的事情,而是在写程序的时候,出了一点小问题~~囧~~
将数据库中一些字段给批量修改了(UPDATE),然后由于没有锁表,直接修改不回去,无奈之下我竟然做了一件让我现在都觉得丢脸的事情——我把Primary Key给删除了~~
PS:这个PK采用的是两个字段联合的
TNND~现在还不明白当时怎么会这样子~~
其实如果仅仅是删除PK还不是最郁闷的事情,而是程序的框架中对于数据的UPDATE是采用Insert UPDATE的方法,结果会经常插入相同的值,以至于设置PK显示有重复键,根本就不成功。
PS:再说一下,数据库表结构是这样子的,一个表,三个字段,key0,key1,value三个,其实key0用来存放一些键值名称,比如total_count,key1用来存放与键值名称对应的id,比如user_id,value不用说了,与前面两个对应的数值。那么total_count和user_id就直接对应了一个人的资料点击数量,比如100。没有采取id自增做主键的原因是key0和key1已经可以确定一个值,没有必要使用id。
于是乎,囧了,又不能锁表(架构决定一旦锁表,服务器就处于挂掉的边缘)。没办法,最后只能拷贝出一张表,对那张拷贝出来的表进行操作,最终建立回原先的表结构,然后改名回去。但是这样子一来,数据丢失在所难免~!~
这次这件事情给我弄得有些龌龊了~~

PHP学习

Memcache笔记

2008年4月25日

一点点关于Memcache的笔记而已。
关于Memcache的安装方法就不说了,去PHPChina搜索一下就能找到了。这里说一下个人对Memcache的一些看法和认识。
对于Memcache,我的理解就是,将内存作为一个容器,然后将一些东西按照index进行标注并且扔进去,等你需要的时候再取出来或者通过一定的数据处理(比如存进数据库或者别的什么)。原理就是,Apache、MySql、PHP对于CPU要求很高,内存要求较低。而memcache恰恰相反,内存要求高,CPU要求低。于是,两厢结合,达到性能最优化~
阅读全文…

PHP学习 ,

Xdebug无限强大

2008年4月9日

XDebug功能很强大啊~~
总是在抱怨PHP的debug不爽,总是echo、var_dump之类。终于忍受不了了,还是用上了Xdebug更爽~~
Xdebug说起来简单,其实也就是将PHP自带的错误输出重写了,并且增加了定位错误的功能,比如这样子,我们写一个错误的PHP函数来看一下

  1. <?php
  2. ecoh();
  3. ?>

这个地方我们把echo错打成ecoh,然后我们执行了之后,原先没有加载Xdebug扩展的时候,只是单纯的告诉我们ecoh这个函数出错了,没有任何的多余信息。等我们装上了Xdebug这个扩展之后,发现给出的错误提示很是详尽。包括运行时间,耗用内存已经所属函数等等。比较的话见图好了
没有装Xdebug的时候 阅读全文…

PHP学习 , ,

挖宝活动如何防止用户作弊(使用数据库)

2008年4月1日

首先说一下这样子的疑惑活动规则。
规则其实很简单:页面上根据一定规律或者概率出现一些宝藏(flash或者图片),你点击之后会对你当前用户进行奖励,比如增加用户积分或者可以计数并且兑换显示奖品等等。
我做过两次这样子的活动,第一次非常成功,基本上不存在作弊;而第二次简直是惨不忍睹,作弊的一片一片的,如果不是因为每天挖宝数量有限制,我相信数据库早就崩溃了~
整理了一下,原因有如下几点:
1.规则验证不够
2.检验方法不当
3.前期没有规划好~
放开第三点不谈,我们来谈谈前两点。
无论如何有一点必须要确认,就是最后对数据库操作一定是需要PHP对数据库进行操作。所以,最后的操作一定会出现在某个PHP文件中。那么首先在这个操作数据的PHP文件一定要进行条件判断
然后,既然出现Flash或者图片,那么就需要有觉悟,这个Flash或者图片用户一定可以得到。那么对于Flash的加密是必须的,否则得到Flash解开就能看到所有的操作。
第三、不要指望第二点中的加密就可以防止用户获取真实的加分PHP文件的地址。不要忘记了,嗅探器到处都是。
OK,现有情况分析清楚了~~总结出来就是一句话,加分的PHP文件,只要用户有心,他一定可以得到~
所以,现在所有的问题都出现在一个地方,对这个PHP文件进行条件判断。
当然,这个具体都需要对某个活动进行分析,不过,以下两点还是需要的

  1. 用户是否登录
  2. 用户是否可以进行加分。如果有些活动每天只能规定数量不能超过20,那么你必须判断有没有超过20

那么,是不是做到这些就够了?肯定不是了~
如果一个人他只拿到1个,然后他不断的访问这个PHP文件,不就会慢慢的增加了?那么对于其他用户肯定是不公平的~
我一直都认为我很驽钝,这次再次让我验证了~其实这个地方也很好办。
回归到挖宝的规则,我们可以发现,这个挖宝的东西怎么来的呢?其实很简单,那就是在某个页面生成,然后出现了Flash,我们点击了Flash之后才可以拿到这个宝石~整个过程有三个过程,Flash仅仅是起到了中间的作用,连接了加分PHP和页面罢了~所以,我们可以采用非常简单的办法来判断我们访问这个加分PHP文件之前,是否在某个页面生成过让你点击获取加分Flash!!所以,我们可以通过页面的URL和一个当前时间戳的值来给一个确定存在的宝石“验明正身”。我们在点击页面出现的Flash或者图片时候,会在后台传递这两个值来给文件判断。首先,这个宝石是否存在!如果不存在自然可以判断你是作弊;第二:这个宝石是否被人领取过了。正常情况,当然不会被人领取!如果是你已经领取过了然后重复访问的话,那么绝对可以判定是作弊!!
OK,到现在为止,我么成功的使用数据库来防止了用户作弊。
当然,如果为了防止一个页面过多的出现宝石(有无聊人会顶住一个页面刷新),也可以在生产宝石的过程中进行判断,同一个页面对应的时间戳是否大于某个值(比如3600,也就是一个小时),如果是,那么就生成新的数据库记录;否则,不生成相应的数据库记录,同时Flash也不会显示。这样子就可以堵住一些人盯住一个页面玩命刷新的情况。
上面这种做法其实还是比较低效,因为整个过程中访问中有一次数据库还是负担比较重的:判断数据库中是否有对应的宝石记录。尤其是大量用户一起刷新页面的时候,这种现象尤其严重。如果加上一些人恶意刷新的时候,更加严重。
所以,如果条件允许的话,使用memory_cache来进行那个步骤。将url和时间戳存在memory_cache中,读取确认之后将其清除,这样子的话,效率会有不小的提升。
其实归根结底,最终的思想很简单——不要轻易相信用户的访问都是合法的,他们可能会访问一些原先没有链接的地址(比如文中的加分PHP),所以任何条件下对于所有的PHP,尤其是可以接受用户数据或者无条件直接更新数据库的文件,必须,并且是一定要进行条件判断!无论如何都不要相信用户的数据或者操作时合法的!!

PHP学习

ThinkPHP学习笔记(2)

2008年3月13日

OK.Let go on~
上次说到config.php文件的配置。那么,肯定要问一下,如何判断能否连接上呢?OK,今天我们就来验证一下这个问题,顺便说一下Action和Model的基本内容。
在我们开始之前,首先建立一个数据库表。由于我们是简单的CMS,那么数据库表也是非常简单。SQL语言如下

  1. CREATE TABLE `test`.`cms_article` (
  2. `id` INT NOT NULL AUTO_INCREMENT ,
  3. `title` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
  4. `content` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
  5. `category_id` INT NOT NULL DEFAULT '0',
  6. `comment_num` TINYINT( 3 ) UNSIGNED NOT NULL ,
  7. PRIMARY KEY ( `id` )
  8. ) ENGINE = MYISAM

这样子我们就把我们需要的数据库建立好了。然后,我们开始对这个数据库进行操作吧。
操作数据库之前,我们要建立一个Model。在说Model和Action之前,先交代一下Model和Action的保存位置。Model保存在程序目录中lib/Model文件夹中,Action保存在程序目录中lib/Action文件夹中。ThinkPHP系统默认的Model规则是这样子的:Model文件文明名类似“Model类名+Model.class.php,并且Model默认的操作数据库表名字为我们在config.php中定义的DB_PREFIX+Model类名,Model类名和文件名需要大写”在Model文件中,定义一个类,扩展Model类,一般写法如下

class 类名Model extends Model{
}

那么,现在我们来定义一个Model吧。
由于我们数据库表名称为cms_article,

class ArticleModel extends Model{

}

文件保存为ArticleModel.class.php。什么都不用写,一个Model已经定义完成了。那么现在,我们继续我们的Action知识吧。
Action和Model很多的规则很接近,不同的是Action不直接操作数据库,而是需要通过Model对数据库进行操作。现在我们来定义一个Action来完成操作。

class IndexAction extends Action{
function index(){
$Article = D(”Article”);
}
}

将文件保存为IndexAction.class.php。OK,现在我们刷新一下首页,如果没有任何的提示,那么恭喜你,数据库连接Model、Action定义都是正常的。Action中D方法就是调用Model,Article就是我们刚刚定义的那个ArticleModel.class.php中的Model类~也就是说在定义Model的同时,我们已经完成了对数据库的连接和对数据库表操作的准备~
OK,这次就这样子了。下次说一下基本的CURD方法,也就是create、update、read、delete四种数据库的操作方法~~

ThinkPHP学习 ,