用PHP将科学计数法转为正常数字的函数实例
PHP实现将科学计数法转换为原始数字字符串的方法实现代码如下:
代码如下 | 复制代码 |
function NumToStr($num){ if (stripos($num,'e')===false) return $num; $num = trim(preg_replace('/[='"]/','',$num,1),'"');//出现科学计数法,还原成字符串 $result = ""; while ($num > 0){ $v = $num - floor($num / 10)*10; $num = floor($num / 10); $result = $v . $result; } return $result; } |
希望本函数对学习php的同学有所帮助。
本文实例分析了php通过记录IP来防止表单重复提交方法。分享给大家供大家参考。具体分析如下:
这个原理比较的简单就是用户第一次提交时我们记录提交用户的IP地址,这样如果用户在固定时间内再次提交表单就会提示重复提交了,这种做法通常用于在顶一下,支持一下这种应用中了,在防止数据重复提交是一个非常不好的选择.
例子,代码如下:
代码如下 | 复制代码 |
<?php session_start(); if(empty($_SESSION['ip']))//第一次写入操作,判断是否记录了IP地址,以此知道是否要写入数据库 { $_SESSION['ip']=$_SERVER['REMOTE_ADDR'];//第一次写入,为后面刷新或后退的判断做个铺垫 mysql_query("INSERT INTO admin(id, name, age) VALUES(123, '姚明', 25)");//写入数据库操作 } else//已经有第一次写入后的操作,也就不再写入数据库 { echo '请不要重复提交表单或刷新页面';//写一些已经写入的提示或其它东西 } ?> |
还有办法就是:
1:在页面生成随机码,也就是每次提交随机码都不一样,在提交的时候验证随机码!
2:在提交的时候,验证如果数据存在,就不提交了.
如果你想防止重复提交入库IP不是最好的办法,我们可以在数据库中查询是不是有相同记录并且IP是不是想同再进行处理.
例子,代码如下:
代码如下 | 复制代码 |
$sql ="select * from 表名 where buy_tel='电话' and IP='$ip' ";// and $time-buy_date<60 $query = $db->query( $sql ); if( $db->rows( $query ) ) { echo('<script>alert("您己提交过了,请勿重复提交!");</script>'); } else { //进行入库操作 } |
希望本文所述对大家的PHP程序设计有所帮助。 之前听到过的一个前辈关于php性能优化的说法——PHP为我们提供了那么多的原声函数,我们尽量用原生函数解决问题。但是有时在想,php原生态的函数就一定快吗?现在看到一个国外的人写的函数,就来测试一下。
今天在阅读kohana源码中的Arr类的时候发现了这样一个函数
代码如下 | 复制代码 |
/** * Fill an array with a range of numbers. * * // Fill an array with values 5, 10, 15, 20 * $values = Arr::range(5, 20); * * @param integer $step stepping * @param integer $max ending number * @return array */ public static function range($step = 10, $max = 100) { if ($step < 1) return array(); $array = array(); for ($i = $step; $i <= $max; $i += $step) { $array[$i] = $i; } return $array; } |
看到这里的时候,我发现php的原声函数也是可以实现这个功能的,忽然想到之前听到过的一个前辈关于php性能优化的说法——PHP为我们提供了那么多的原声函数,我们尽量用原生函数解决问题。于是我就做了个测试,看看php原生函数性能究竟比自己写的快多少。要测试的函数有原生函数range()和上面的函数_range(),这里加下划线开始是因为重写原声函数range()会报错“Fatal error: Cannot redeclare range() in”。
代码如下 | 复制代码 |
function _range($step = 10, $max = 100) { if ($step < 1) return array(); $array = array(); for ($i = $step; $i <= $max; $i += $step) { $array[$i] = $i; } return $array; } $time['begin'] = microtime(true); $tmp = range(0,1000000,3); //$tmp = _range(0,1000000,3); $time['end'] = microtime(true); echo $time['end'] - $time['begin'].'s'."r"; echo (memory_get_peak_usage()/1024/1024)."M"; |
分别用原生函数和自定义函数进行测试,在产生0~1000000之间所有的3的倍数时,结果出乎我的意料:
首先是使用原生函数的结果:
下面是使用自定义函数的结果:
为了结果比较准确,我在做个图表统计
统计次数 原生函数range() 自定义函数_range()
(0,1000000,3) 5.155E-3s 27.5530M 1.907E-5s 0.1241M
(0,1000000,2) 7.479E-3s 40.2688M 1.811E-5s 0.1241M
(0,1000,1) 8.16E-5s 0.1620M 2.649E-5s 0.1241M
从表中可以看出产生随机数时自定义函数比原生函数要节省内存和时间,而且原生函数在生成大量随机数时特别耗内存,消耗时间也特别多,而自定义函数在这方面则表现得好,产生的内存和消耗的时间基本稳定,看来前面那位前辈说的不一定完全正确哦,但是这里要注意我们这里的自定义函数只能生成数字,而原生的range还可以产生字母的,但是我想这自定义函数添加个字母应该也不会太难~
看来kohana官方对range这个函数很是了解,对php内核中该函数的复杂度也很了解,所以这个小优化才可以做这么好,太厉害了!!!
偶尔在网上看到关于php的伪重载的问题,有点兴趣便研究了一下。下面作者将说说php如何利用func_get_arg,func_get_args,func_num_args实现函数的伪重载问题。
首先说说方法重载的好处:
实现方法重载可以不用为了对不同的参数类型或参数个数,而写多个函数。多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。如果我们使用reflector去查看微软写的.net的基类库的话,我们可以发现他使用很多的方法重载,这样我们在调用的时候,就不需要记那么多的方法名称,而是知道了方法的功能就可以直接的给他传递不同的参数,编译器会明确的知道我们调用了哪一个方法。
但是在PHP中没有函数重载这个概念,让很多时候我们无法进行一些处理,甚至有时候不得不在函数后面定义好N个参数来解决相关问题,而php提供了几个函数,比如:func_get_arg,func_get_args,func_num_args 却可以直接解决相关问题。具体举个示例代码如下:
代码如下 | 复制代码 |
<?php function testOne($a) { echo ('一个参数就这样 '); } function testTwo($a, $b) { echo ('两个参数的就这样 '); } function testThree($a, $b, $c) { echo ('呵呵,这是三个参数的 '); } function test() { $argNum = func_num_args(); // 这一段其实可以用 $_arg = func_get_args() 来获得所有的参数,只是要用数组而已,不方便我下面的表达,呵呵 for ($i = 0; $i < $argNum; $i++) { $_arg_{$i} = func_get_arg($i); } switch ($argNum) { case 1 : testOne($_arg_1); break ; case 2 : testTwo($_arg_1, $_arg_2); break ; case 3 : testThree($_arg_1, $_arg_2, $_arg_3); break ; default : echo (' 这是没有参数的情况 '); break ; } } /** * 例子的实现 */ test(); echo ('<br>'); test(1); echo ('<br>'); test(1, 2); echo ('<br>'); test(1, 2, 3); // 这些只是在函数中的运用,其实最主要的还是在类中的运用 // 如果这些用到类里面我就不需要担心构造函数是否有几个参数了,不是吗? // 类里面的运用只举一个简单的例子 class test{ var $a = 0; var $b = 0; function test() { $argNum = func_num_args(); $_arg = func_get_args(); switch ($argNum) { case 1 : $this->test1($_arg[0]); break ; case 2 : $this->test2($_arg[0], $_arg[1]); break; default : $this->a = 0; $this->b = 1; break; } } function test1($a) { $this->a = $a; } function test2($a, $b) { $this->a = $a; $this->b = $b ; } } |
友情提示
php的的func_num_args、func_get_arg和func_get_args都是返回函数实参相关的函数。
func_num_args:实参个数;
func_get_arg:返回某一个实参,必须事实参数组的索引;
func_get_args:返回实参数组;
strtotime函数的使用在时间日期处理上是非常的强大了,这里我们一起来看看strtotime函数内核与常用方法。PHP strtotime函数将任何英文文本的日期时间描述解析为Unix时间戳[将系统时间转化成unix时间戳]
一,获取指定日期的unix时间戳 strtotime(”2009-1-22″) 示例如下:
echo strtotime(”2009-1-22“) 结果:1232553600
说明:返回2009年1月22日0点0分0秒时间戳
二,获取英文文本日期时间 示例如下:
便于比较,使用date将当时间戳与指定时间戳转换成系统时间
代码如下 | 复制代码 |
(1)打印明天此时的时间戳strtotime(”+1 day“) (2)打印昨天此时的时间戳strtotime(”-1 day“) (3)打印下个星期此时的时间戳strtotime(”+1 week“) (4)打印上个星期此时的时间戳strtotime(”-1 week“) (5)打印指定下星期几的时间戳strtotime(”next Thursday“) (6)打印指定上星期几的时间戳strtotime(”last Thursday“) |
以上示例可知,strtotime能将任何英文文本的日期时间描述解析为Unix时间戳,我们结合mktime()或date()格式化日期时间获取指定的时间戳,实现所需要的日期时间。
现在我们深入分析它的源码
源码位置:\ext\date\php_date.c
代码如下 | 复制代码 |
/* {{{ proto int strtotime(string time [, int now ]) timelib_time *t, *now; tzi = get_timezone_info(TSRMLS_C); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, “sl”, ×, &time_len, &preset_ts) != FAILURE) { initial_ts = emalloc(25); if (!time_len) { t = timelib_strtotime(times, time_len, &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); timelib_time_dtor(now); if (error1 || error2) {
|
strtotime函数在使用strtotime(“-1 month”)求上一个月的今天时会出一些状况,
因此也引出写这篇文章,本文包括如下内容:
strtotime函数的一些用法
strtotime函数的实现基本原理
strtotime(“-1 month”)求值失败的原因
strtotime函数的一些用法
1、 strtotime(“JAN”)和strtotime(“January”)
这两个用法的效果是一样的,都是返回指定月份的今天,如果指定月份没有今天,则顺延到下一个月。 如在2011-03-31计算二月,代码:
echo date("Y-m-d H:i:s", strtotime("feb", strtotime("2011-03-31")));
程序会输出: 2011-03-03 00:00:00。 从表象来看,这个结果也许不一定是我们想要的,但是这也算是一种解决方案,这种方案是由什么决定的呢? strtotime函数在执行月份的计算时只计算了月份,相当于直接将月份设置为指定的月份的值,而如jan,january都会有一个对应内部数值。
2、 first关键字
first是一个辅助型的关键字,它可以与星期,天等可以指定确认值的关键字组合使用,如求2011年的第一个星期天:
echo date("Y-m-d H:i:s", strtotime("second sunday", strtotime("2011-01-01"))), "<br />";
在PHP的源码中,对于first与星期和天的组合使用是分开的,即first day对应一个处理操作, 在最终的C实现中,天的值指定为1,即time结构中的d字段指定为1,如下代码:
代码如下 | 复制代码 |
switch (time->relative.first_last_day_of) { case 1: /* first */ time->d = 1; break; case 2: /* last */ time->d = 0; time->m++; break; } |
3、previous和next关键字
与first类似,previous关键字可以与星期,天组合使用,表示指定时间的前一个星期几或前一天。如下所示代码:
echo date("Y-m-d H:i:s", strtotime("previous sunday", strtotime("2011-02-01"))), "<br />";
程序会输出:2011-01-30 00:00:00
程序求2011-02-01的前一个星期天。
next关键字与previous相反,它表示下一个星期几或后一天。
4、 last关键字
last关键字既可以作为上一个,也可以作为最后一个。如求上一个星期天的日期:
代码如下 | 复制代码 |
echo date("Y-m-d H:i:s", strtotime("last sunday", strtotime("2011-02-05"))), "<br />"; |
程序会输出: 2011-01-30 00:00:00
当程序作为最后时,其应用场景是指定日期所在月的最后一天,相当于date(“t”)的结果。如求2000年2月的最后一天:
代码如下 | 复制代码 |
echo date("Y-m-d H:i:s", strtotime("last day", strtotime("2000-02-01"))), "<br />"; |
first、previous、last和this关键字在re文件中属于同一组。
5、 back和front关键字
这两个关键字是对一天中的小时的向前和向后操作,其调用格式如下:
echo date("Y-m-d H:i:s", strtotime("back of 24", strtotime("2011-02-01"))), "<br />";
echo date("Y-m-d H:i:s", strtotime("front of 24", strtotime("2011-02-01"))), "<br />";
back表示将时间设置指定小时值的后一个小时的15分的位置。如果是24点,则算到第二天的0点15分。
front表示将时间设置指定小时值的前一个小时的45分的位置。如果是0点,则算前一天的23点45分。
上面的代码输出:2011-02-02 00:15:00 2011-02-01 23:45:00。 其中back of和front of后接的数组必须大于等于0并且小于等于24。
strtotime函数的实现基本原理
官方文档对于strtotime函数的说明是这样的:本函数预期接受一个包含美国英语日期格式的字符串并尝试将其解析为 Unix 时间戳 (自 January 1 1970 00:00:00 GMT 起的秒数),其值相对于 now 参数给出的时间,如果没有提供此参数则用系统当前时间。
这是一个标准PHP内置函数,从PHP4起就已经存在。strtotime函数是以一个扩展的方式加载进来的,在ext/date目录下有其全部实现。 作为一个标准的内置函数,其定义格式也是标准的,如下:
代码如下 | 复制代码 |
PHP_FUNCTION(strtotime) // 调用相关函数,实现字符串的解析和结果计算 // 返回结果 |
在输入处理中,先识别两个参数都存在的情况并进行处理,如果不是此种状态,则处理第二个参数不存在的情况, 如果都没有,则报错,返回FALSE。
strtotime函数的第一个参数是一个字符串,对于这个字符串,由于其复杂性,PHP使用了其词法解析一样的工具:re2c。在/ext/date/lib目录下,从parse_date.re文件我们可以看到其原始的re文件。 当用户以参数的形式传入一个字符串,此字符串将交给此程序处理,针对其字符串的不同,匹配不同的处理函数。 如strtotime(“yesterday”)调用,分析字符串时,将匹配yesterday字符串,此字符串对应函数如下:
代码如下 | 复制代码 |
'yesterday' s->time->relative.d = -1; typedef struct Scanner { struct timelib_time *time; typedef struct timelib_time { timelib_sll sse; /* Seconds since epoch */ unsigned int have_time, have_date, have_zone, have_relative, have_weeknr_day; unsigned int sse_uptodate; /* !0 if the sse member is up to date with the date/time members */ typedef struct timelib_rel_time { int weekday; /* Stores the day in 'next monday' */ int first_last_day_of; timelib_special special; |
s->time->relative.d = -1;所表示的意思是当前时间的相对天数是-1。 这只是中间词法解析的中间结果,但是最后结果是通过这些中间结果计算出来的。
strtotime(“-1 month”)求值失败的原因
虽然strtotime(“-1 month”)这种方法对于后一个月比前一个月的天数的情况会求值失败,但是从其本质上来说,这并没有错。 PHP这样实现也无可厚非。只是我们的需求决定了我们不能使用这种方法,因此我们称其为求值失败。
我们来看它的实现过程,由于没有第二个参数,所以程序使用默认的当前时间。 第一个参数传入的是-1 month字符串,这个字符串所对应的re文件中的正则为:
代码如下 | 复制代码 |
reltextunit = (('sec'|'second'|'min'|'minute'|'hour'|'day'|'fortnight'|'forthnight'|'month'|'year') 's'?) | 'weeks' | daytext; relnumber = ([+-]*[ \t]*[0-9]+); |
最终relative会对应一系列操作,程序会识别出前面的-1 和后面的month字符串,month对应一种操作类型:TIMELIB_MONTH。 在此之后,根据识别出来的数字和操作类型执行操作,如下代码:
代码如下 | 复制代码 |
case TIMELIB_MONTH: s->time->relative.m += amount * relunit->multiplier; break; |
如上代码,则是直接记录月份的相对值减一。 但是对于类似于3月31号这样的情况,2月没有31号,程序会自动将日期计算到下一个月。
相关文章
- eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
- 在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
Python astype(np.float)函数使用方法解析
这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08- Create Procedure AtoC @ChangeMoney Money as Set Nocount ON Declare @String1 char(20) Declare @String2 char(30) ...2016-11-25
- 这篇文章介绍了C#判断字符串是否数字或字母的实例,有需要的朋友可以参考一下...2020-06-25
- 这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
- 这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
- 这篇文章主要为大家详细介绍了C#实现猜数字游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
PHP函数分享之curl方式取得数据、模拟登陆、POST数据
废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07- Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
- 设置登录密码我们一般会有限制的如由什么组合了,下面我们来看一篇关于安卓开发之设置密码只能输入字母和数字的组合方法,具体的细节如下所示。 无论是电脑还是手机...2016-09-20
- PHP 函数 strip_tags 提供了从字符串中去除 HTML 和 PHP 标记的功能,该函数尝试返回给定的字符串 str 去除空字符、HTML 和 PHP 标记后的结果。由于 strip_tags() 无法实际验证 HTML,不完整或者破损标签将导致更多的数...2014-05-31
SQL Server中row_number函数的常见用法示例详解
这篇文章主要给大家介绍了关于SQL Server中row_number函数的常见用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-08- 分享一个PHP加密解密的函数,此函数实现了对部分变量值的加密的功能。 加密代码如下: /* *功能:对字符串进行加密处理 *参数一:需要加密的内容 *参数二:密钥 */ function passport_encrypt($str,$key){ //加密函数 srand(...2015-10-30