PHP简单计数器实例程序
让我们在首页上加上一个计数器。有利于演示怎样读写文件以及创建自己的函数。counter.inc包含以下代码:
代码如下 | 复制代码 |
<? 然后我们更改front.php3文件以显示这个计数器: <? |
例2
代码如下 | 复制代码 |
1)文本计数器 |
1.类命名
(1)使用camel命名法(这个几乎所有语言通用)
(2)尽量少于3个词
(3)缩写词也不要全部使用大写字母。eg:使用GetHtmlStatic, 而不使用GetHTMLStatic。
2.函数和方法命名
通常每个方法和函数都执行一个动作,所以对它们的命名应该清楚地说明它们的用途。
eg:用CheckForErrors()代替ErrorCheck(),用DumpDataToFile代替DataFile().
3.类属性命名
属性命名应该以字符"m" 为前缀。前缀”m“后采用于类命名一致的规则。
eg: var mVar;
4.变量命名
使得所有的变量在代码中看起来都不同,容易辨认。
局部变量命名:所有字母都使用小写,使用 ”_“ 作为每个词的分界
eg:$time_of_error
全局变量命名:带前缀 "g"
eg: global $gLog;
静态变量命名:带前缀 "s"
eg: static $msStatics = 0;
引用变量命名:带前缀 ”r“
eg: var mrStatus;
string,字符串型,在变量前面加str
代码如下 | 复制代码 |
//下面一个变量为字串型 $strMessage = Hello World! ; //下面一个变量为一维数组 //下面一个变量为整数
$rsConn = mysql_connect ( localhost , user , pw ) ; |
未明变量,使用mx
代码如下 | 复制代码 |
$mxData = getData() ; |
自定义函数,使用fn_开头
代码如下 | 复制代码 |
function fn_HaltError ( $strErrorMessage ) { // do sth... } |
一个综合的例子(使用分页类):
代码如下 | 复制代码 |
include ( "lib/BluePage.class.php" ) ; $rsConn = mysql_connect( localhost , root , 123456 ) or d $strQuery = "SELECT COUNT(`id`) FROM test" ; //分页数组与html // 分页数据里包含有offset,取数据 |
手册上的一个有意思的小示例。
http://www.php.net/manual/zh/language.variables.basics.php
代码如下 | 复制代码 |
$this = 'text'; // error echo $$name; |
在PHP的词法分析时,$this变量是符合其规则的,在语法解析生成中间代码时,PHP内核会根据变量类型在生成赋值的中间代码时判断是否为$this变量,如果是则报错。这里为什么要报错呢?因为this作为一个特殊的变量,在对象的成员方法等调用初始化时会将this变量添加到活动符号表。
在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性。
当一个方法在类定义内部被调用时,有一个可用的伪变量 $this。$this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。
在词法分析、语法分析并生成中间代码时,$this作为一个特殊的变量存在,特别是在生成中间代码时,代码中充斥着对于this的特殊处理。这些都是为后面的运行做准备,如识别标记出某处使用this变量,在存储opcode的zend_op_array结构体中专门有一个变量this_var标识是否有this变量。一个函数或一个类方法都会生成一个新的zend_op_array,在生成中间代码时,判断当前变量是否为this变量。
this变量在执行过程中会有两种存在状态,一种是全局传递的状态,存储在EG(This),一种是当前作用域状态,以this变量存储在EG(active_symbol_table)(当前执行环境的活动符号表)。
在我们执行一个 op_array 时,比如一个对象的方法,PHP内核会给这个 op_array 生成一个 zendexecutedata ,在生成初始化时,EG(This) 会添加到EG(active_symbol_table) 。
在方法调用过程中,如果有用到this变量,则会直接取EG(active_symbol_table)的值。
那么一个对象中的EG(This)在哪里初始化呢?
就EG(This)变量本身来说,在我们初始化PHP的执行环境时,它和其它全局变量(如EG(scope)等)一样都会被初始化为NULL。
对于一个对象来说,当我们创建了一个对象,调用时,PHP内核会将当前获得的对象直接赋值给EG(This),而这个当前获得的对象是在通过new操作生成对象时创建的对象本身。
如下这个简单示例:
代码如下 | 复制代码 |
class Foo { public $var = 10; function t() { echo $this->var; } function t2() { echo 33; } } $foo = new Foo(); $foo->t(); |
其主程序流程生成的中间代码如下:
代码如下 | 复制代码 |
function name: (null) number of ops: 8 compiled vars: !0 = $foo line # * op fetch ext return operands --------------------------------------------------------------------------------- 2 0 > NOP 15 1 ZEND_FETCH_CLASS 4 :1 'Foo' 2 NEW $2 :1 3 DO_FCALL_BY_NAME 0 4 ASSIGN !0, $2 16 5 ZEND_INIT_METHOD_CALL !0, 't' 6 DO_FCALL_BY_NAME 0 7 > RETURN 1this |
变量原始的对象值出生在 opcode NEW,经过了赋值(ASSIGN)后,在方法初始化时,将变量本身传递给执行环境的调用者,调用者又在执行调用(DO_FCALL_BY_NAME)时将变量传递给EG(This),当执行这个方法的op_array时,初始化当前作用域的环境(zend_execute_data)时,会将EG(This)作为$this变量添加到活动符号表,后续方法中的$this变量的使用就会直接取符号表的变量。
在php浮点数处理函数在php中有很多,包括有如ceil,floor,round,intval 经过他们处理之后可返回我们想要的浮点数小数位了,下面我来介绍一些关于php浮点数用法与问题分析。一,php浮点数用法
PHP浮点类型取整之ceil — 进一法取整
说明
float ceil ( float value )
返回不小于 value 的下一个整数,value 如果有小数部分则进一位。ceil() 返回的类型仍然是 float,因为 float 值的范围通常比 integer 要大。
例子 1. ceil() 例子
代码如下 | 复制代码 |
< ?php |
PHP浮点类型取整之floor — 舍去法取整
说明
float floor ( float value )
返回不大于 value 的下一个整数,将 value 的小数部分舍去取整。floor() 返回的类型仍然是 float,因为 float 值的范围通常比 integer 要大。
例子 1. floor() 例子
代码如下 | 复制代码 |
< ?php |
PHP浮点类型取整之round — 对浮点数进行四舍五入
说明
float round ( float val [, int precision] )
返回将 val 根据指定精度 precision(十进制小数点后数字的数目)进行四舍五入的结果。precision 也可以是负数或零(默认值)。
例子 1. round() 例子
代码如下 | 复制代码 |
|
PHP浮点类型取整之intval—对变数转成整数型态
例子intval()
代码如下 | 复制代码 |
< ?php echo intval(4.3); //4 echo intval(4.6); // 4 ?> |
二,浮点数转成字符串
PHP内置的echo, var_dump, json_encode, 字符串拼接等函数(指令)在显示浮点数时都有问题, 导致精度丢失.
代码如下 | 复制代码 |
<?php $a = 1315537636.338467; printf("%f", $a); echo "n"; echo $a . "n"; echo $a; echo "n"; ?> 结果 1315537636.338467 1315537636.3385 1315537636.3385 |
也就是说, 用PHP最顺手的方法将浮点数转成字符串或者显示是不行的, 必须使用printf/sprintf将浮点数转成字符串.
三,一个常见问题的解答
不过, 我当时遗漏了一点, 也就是对于如下的这个常见问题的回答:
代码如下 | 复制代码 |
<?php |
为啥输出57
为啥输出是57啊? PHP的bug么?
我相信有很多的同学有过这样的疑问, 因为光问我类似问题的人就很多, 更不用说bugs.php.net上经常有人问…
要搞明白这个原因, 首先我们要知道浮点数的表示(IEEE 754):
浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).
符号位:最高位表示数据的正负,0表示正数,1表示负数。
指数位:表示数据以2为底的幂,指数采用偏移码表示
尾数:表示数据小数点后的有效数字.
这里的关键点就在于, 小数在二进制的表示, 关于小数如何用二进制表示, 大家可以百度一下, 我这里就不再赘述, 我们关键的要了解, 0.58 对于二进制表示来说, 是无限长的值(下面的数字省掉了隐含的1)..
0.58的二进制表示基本上(52位)是:
0010100011110101110000101000111101011100001010001111
0.57的二进制表示基本上(52位)是:
0010001111010111000010100011110101110000101000111101
而两者的二进制, 如果只是通过这52位计算的话,分别是:
0.58 -> 0.57999999999999996
0.57 -> 0.56999999999999995
至于0.58 * 100的具体浮点数乘法, 我们不考虑那么细, 有兴趣的可以看(Floating point), 我们就模糊的以心算来看… 0.58 * 100 = 57.999999999
那你intval一下, 自然就是57了….
可见, 这个问题的关键点就是: “你看似有穷的小数, 在计算机的二进制表示里却是无穷的”
四,float(浮点数)比较的问题
最近在开发一个合同管理系统的时候,涉及到两个浮点数比较,算是把我郁闷惨了。
在N久以前,就不晓得从哪里听来的一个“不要用等号去比较浮点数”的“真理”,自己平时也在用,好像没有出现啥问题,可这次问题总算是来了。
代码如下 | 复制代码 |
<?php |
结果是:
代码如下 | 复制代码 |
float(12300) |
后来才知道在PHP中,要比较两个浮点数的大小,可以用bccomp(参数1,参数2,小数位)来比较。
代码如下 | 复制代码 |
<?php 结果: float(12300) |
bccomp函数具体用法参与PHP手册
本文章来给各位同学介绍关于PHP的可变变量名使用方法,这个也是刚知道可变变量名了,大家一起来学习一下。
有时候可变的变量名会给编程带来很大的方便。也就是说变量名可以被动态的命名和使用。通常变量通过下面这样的语句来命名 :
代码如下 | 复制代码 |
<?php |
可变变量名指的是使用一个变量的值作为这个变量的名称。在上面的例子中,通过使用两个$符号,你可以把hello设置成一个变量的名称,就像下面那样。
代码如下 | 复制代码 |
<?php $$a = 'world'; ?> |
通过上面的两个语句,有两个变量被定义:变量$a,装的内容是”hello” 以及变量$hello,装的内容是 “world”。 于是,下面的语言:
代码如下 | 复制代码 |
<?php |
跟下面的语句的输出完全一致:
代码如下 | 复制代码 |
<?php |
它们都输出:hello world。
为了使用数组的可变变量名,你需要解决一个歧义问题。就是,如果你写$$a[1],解析器需要明白究竟你的意思是要把$a[1]当成一个变量,还是要把$$a当成变量、[1]指的是这个变量的索引。解决这个歧义问题的语法是:第一种情况使用${$a[1]},第二种情况使用${$a}[1]。
类属性也可以通过可变属性名来访问。可变属性名从产生调用所在的变量的访问范围内获取。例如,如果你的表达式是这样的:$foo->$bar,那么运行时将会在本地变量范围内寻找变量$bar,它的值将会做为$foo对象的一个属性名。如果$bar是个数组也可以使用。
例1 可变变量名
代码如下 | 复制代码 |
<?php 上面的例子将会输出下面的结果: I am bar. I am bar. |
警告
请注意,可变变量名不能用于PHP函数和类里的超级全局数组变量上。变量$this也是一个不能动态取名的特殊变量。
浅谈PHP可变变量安全
变变量是PHP一个非常方便的特性,手册里已经说了,可变变量的意思就是一个变量的变量名可以动态的设置!
那么变量的变量名可以动态设置会产生什么安全问题呢?下面来看看:
代码如下 | 复制代码 |
<?php $a = 'phpinfo'; $a(); ?> |
这段代码很容易理解,变量的类型是字符型phpinfo,变量动态加上了(),于是变量变成了phpinfo函数动态执行了!
按照同样的原理我们引用手册中可变变量的例子:
代码如下 | 复制代码 |
<?php $a = 'phpinfo'; ${$a()}; ?> $a() |
这个动态函数放入动态变量,当然我这个说法有点不专业,还是可变变量,我们会发现phpinfo函数还是执行了!
看过手册还有我给出的这个例子的话,大家一定觉得这个一点都不神奇,这就是PHP的语法特性,然后我们把这个东西再进化缩成一行:
代码如下 | 复制代码 |
<?php $a = "${${phpinfo()}}"; ?> |
这是一个2个嵌套的可变变量,我们只是按照上面一个例子将可变变量的内容自己填写进去了,实际上就是把某个函数赋给某个变量,所以phpinfo函数最终执行了,也就化成了各种漏洞和webshell的原型!
看到这里大家应该知道了,为什么当初大牛们要我去看PHP手册吧,然而本文到这里就结束了么,咱还漏了一点,大牛说了安全就是基础,咱其实还没把这个东西搞清楚,为什么前面例子的变量是用的单引号,而后面的最终的例子用的是双引号,如果你想到了这个问题,我觉得你做安全肯定非常有潜力,以后保不准就是一大牛!
PHP中单引号和双引号的区别还是和变量有关,来看下面的例子:
代码如下 | 复制代码 |
<?php $a = 'phpinfo()'; echo $a; //输出phpinfo()字符串 echo '$a'; //输出$a字符串 echo "$a"; //输出phpinfo()字符串 ?> |
双引号里的内容会再经过PHP的语法解析变量,而单引号里的内容就直接定性为字符串了!
所以本文到这里就真正结束了,于是大家应该也都明白了,当初牛人为什么和我说多看PHP手册和安全就是基础的深意。
相关文章
- 最基础的对数据的增加删除修改操作实例,菜鸟们收了吧...2013-09-26
- 主键与外键的关系,通俗点儿讲,我现在有一个论坛,有两张表,一张是主贴 thread,一张是回帖 reply先说说主键,主键是表里面唯一识别记录的字段,一般是帖子id,体现在访问的时候,例如是 thread.php?id=1 表示我要访问的是帖子...2015-11-24
- 在MySQL中,InnoDB引擎类型的表支持了外键约束。 外键的使用条件: 1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持); 2.外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时...2015-11-24
- 这篇文章主要介绍了c#接口使用的实例,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-17
- 一、数据访问对象 (DAO)YiiDAO 基于 PHP Data Objects (PDO) 构建。它是一个为众多流行的DBMS提供统一数据访问的扩展,这些 DBMS 包括MySQL, PostgreSQL 等等。因此,要使用 Yii DAO,PDO 扩展和特定的 PDO 数据库驱动(例如...2015-11-24
- C# 实现简单打印的实例代码,需要的朋友可以参考一下...2020-06-25
- 这篇文章主要介绍了C#中的IEnumerable简介及简单实现实例,本文讲解了IEnumerable一些知识并给出了一个简单的实现,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了Java利用Redis实现高并发计数器的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 在这一章里你将了解到迷人而又让人容易糊涂的套接字(Sockets)。Sockets在PHP中是没有充分利用的功能。今天你将看到产生一个能使用客户端连接的服务器,并在客户端使用sock...2016-11-25
- 这篇文章主要介绍了利用C++内核对象封装的类,程序只能运行单个实例,可防止多次启动,大家参考使用吧...2020-04-25
- [ajax介绍] ajax是使用客户端脚本与web服务器交换数据的web应用开发方法。web页面不用打断交互流程进行重新加裁,就可以动态地更新。使用ajax,用户可以创建接近本地...2016-11-25
- ob_start([string output_callback])- 打开输出缓冲区 所有的输出信息不在直接发送到浏览器,而是保存在输出缓冲区里面,可选得回调函数用于处理输出结果信息。 ob...2016-11-25
- 这篇文章主要介绍了C#最简单的字符串加密解密方法,本文直接给出实例代码,需要的朋友可以参考下...2020-06-25
- 本款php计数器是一款用来统计网页的访问次数的简单的讲数器代码,利用txt文本文件与php fopen函数进行操作。 代码如下 复制代码 $log = 'l...2016-11-25
- 使用redux管理数据,由于Store独立于组件,使得数据管理独立于组件,解决了组件之间传递数据困难的问题,非常好用,今天重点给大家介绍使用react+redux实现计数器功能及遇到问题,感兴趣的朋友参考下吧...2021-06-02
- 这篇文章主要为大家详细介绍了Vue实例的一些简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2017-01-23
- 这篇文章主要介绍了Vue实例的选项有哪些,文中讲解非常细致,代码帮助大家更好的学习,感兴趣的朋友可以了解下...2020-06-10
- 今天研究了一下,在C#里面却是可以不用自定义消息这么复杂的方法来实现跨窗体调用控件,C#有更好的办法就是委托。...2020-06-25
- 最终效果 ps简单给偏暗...2016-09-14
- 下面我们来介绍一下关于php实现断点续传的代码,有需要学习的朋友可参考一下。 让PHP下载代码支持断点续传 主要靠的 HTTP协议中header Content-Range来实现 先来...2016-11-25