php函数的传值与传址(引用)详解

 更新时间:2016年11月25日 15:01  点击:2199
在php中我们函数传值就比较简单了,但可能有些朋友地天真无邪函数传址或引用搞不明白,下面小编来给各位介绍在php中函数传值与传址(引用)介绍,希望对各位有所帮助。

php中引用的用法:

1. 变量的引用赋值: $a = &$b

2. 函数调用时的引用参数传递

    1) 早期php是在调用时通过&符号传递引用类型的变量, 比如: func(&$arg);

    2) 后来, 函数的引用类型参数被规定为需要在函数声明时定义, 不如: function func(&$arg);

       注: 引用声明时定义引用类型参数后, 运行时引用参数传递被废弃, 需要在php.ini中增加allow_call_time_pass_reference来开启.

3. 函数返回引用类型, 这种应用方式需要声明函数时, 在函数名前增加&符号, 并且, 在调用时, 要用引用赋值方式, 比如:

 代码如下 复制代码


function &func() {
    return $a;
}
$a = func();  //这种调用方式得到的不是引用传值
$a =& func(); //这样调用才是引用传值

简而言之, 就是让函数的返回一个引用类型的值, 一个更实际的例子:

 代码如下 复制代码

$a = 1;
function &func(&$a) {
  return $a;
}
$b = func($a);
$c =& func($a);
$b = 2;
echo "a: $a, b: $b, c: $c. <br />/n";
//输出a: 1, b: 2, c: 1.
//可见对$b的修改不会影响$a
$c = 3;
echo "a: $a, b: $b, c: $c. <br />/n";
//输出a: 3, b: 2, c: 3.
//可见对$c的修改会影响$a


php函数传值的几个细节

 代码如下 复制代码
//一、基本数据类型的传值  
/* **************************************************** */ 
function testvar($k){
 $k = 40;
}
$c = 30;
//给一个函数参数传一个基本数据类型(整型,布尔,字符 ...), 实际上传的就是值 ;
testvar($c);
echo $c;//结果是:30
 
 
function testvar2(&$k){
 $k = 40;
}
$e = 30;
//给一个函数参数传一个基本数据类型(整型,布尔,字符 ...), 实际上传的y就是地址 ;
testvar2($e);
echo $e;//结果是:40
 
/* **************************************************** */
//二、数组(默认情况下是复制一份数据),如要传地址则&$arr.
$arr1 = array(-1,5,0);
function testArr($arr){
 for($i=0;$i<count ($arr);$i++){
  for($j=$i+1;$j<count($arr);$j++){
   if($arr[$i]>$arr[$j]){
    $temp = $arr[$i];
    $arr[$i] = $arr[$j];
    $arr[$j] = $temp;
   }
  }
 
 }
 print_r($arr);  //结果:Array ( [0] => -1 [1] => 0 [2] => 5 )
}
testArr($arr1);
print_r($arr1);  //结果:Array ( [0] => -1 [1] => 5 [2] => 0 )
 
function testArr2(&$arr){
 for($i=0;$i</count><count ($arr);$i++){
  for($j=$i+1;$j<count($arr);$j++){
   if($arr[$i]>$arr[$j]){
    $temp = $arr[$i];
    $arr[$i] = $arr[$j];
    $arr[$j] = $temp;
   }
  }
 
 }
}
testArr($arr1);
print_r($arr1);  //结果:Array ( [0] => -1 [1] => 0 [2] => 5 )
 
 
 
 
/* **************************************************** */
//三、对象数据类型传值
class person{
 public $name;
 public  $age;
}
 
$a = new person();
$a->name = '小明';
$a->age = '20';
//变量a在存的是对象的地址,把a赋给b这个变量,实际上就是赋了一个地址。
$b = $a;
$b->age = 30;
//echo $a->age.$b->age;//结果是:30 30
//给一个函数参数传一个对象, 实际上传的是这个对象的地址;
function test($k){
 $k->age =40;
}
//调用
test($b);
//echo $a->age.$b->age;//结果是:40 40
</count>

php函数的传值与传址有什么区别呢?对于这样的问题我喜欢通过程序演示来获取答案。让我们来看一个演示记录吧!

 代码如下 复制代码
<?php   
       
$i=100;   
       
function func($n){   
       
   $n=$n+100;   
          
   return $n;   
          
}   
echo '1)函数传值前变量$i的值:'.$i.'<br>';   
echo '2)传值后函数的返回值:'.func($i).'<br>';   
echo '3)函数传值后变量$i的值:'.$i.'<br>';   
echo '4)函数传址前变量$i的值:'.$i.'<br>';   
echo '5)传址后函数的返回值:'.func(&$i).'<br>';   
echo '6)函数传址后变量$i的值:'.$i.'<br>';   
//echo func($i).'<br>';   
?>

程序输出:

1)函数传值前变量$i的值:100
2)传值后函数的返回值:200
3)函数传值后变量$i的值:100
4)函数传址前变量$i的值:100
5)传址后函数的返回值:200
6)函数传址后变量$i的值:200
   
解释:

1)直接输出一个赋值$i=100的变量
2)func函数传值返回一个算术相加的结果$=100+100
3)func函数传值,其作用区域只限于函数内部,对外面的变量$i不会有影响
4)同上
5)func函数参数前多了个"&"符,表示传址,和2)一样,返回值是函数的算术运行结果。

6)func(&$i),变量指针指向$i的位置,可以理解为是对变量$i的操作,$i=$i+100;这时变量$i已经相当于重新被赋值

如果去掉上面代码的第18行注释,会得什么结果呢?

小结:传址为了在执行函数的同时,同时改变函数参数值,而传值不期望改变。

本文章来给大家整理一下关于php面向对象中子类中重载父类详解,希望此文章对各位理解php子类中重载父类有所帮助哦。


因为在PHP中不能存在同名的函数,所以在同一个类中也就不能定义重名的方法。这里所说的重载是指在    子类中可以定义和父类同名的方法从而覆盖从父类中继承过来的方法。


子类中重载父类的方法

 代码如下 复制代码


<?php
      class Person{
                                                              
           public $name;     
                                                             
           public function __construct($name="" ){
                $this->name =$name;
                                                                      
           }
           public  function say(){
                echo "我叫".$this->name  ;
           }
                                                                 
 }
 ?>
 <?php
      class Student extends Person{
                                                              
           public $name;             
                                                             
           public function __construct($name=""){
                $this->name =$name;
                                                         
           }
 //这里定义了一个和父类中同名的方法,将父类中的说话方法覆盖并重写
           public  function say(){
                echo "我叫".$this->name .",今年25岁了" ;
           }
                                                                 
 }
 ?>

重写方法与访问权限

子类中的覆盖方法不能使用比父类中被覆盖方法更严格的访问权限。

如果父类中的方法的访问权限是protected,那么子类中重写的方法的权限就要是protected或者public;    如果父类中的方法是public,那么子类要重写的方法的权限就只能是public。也许这也就是为什么子类可    以继承父类的私有成员,但却不能使用的原因吧。


重写时的参数数量

子类可以拥有与父类不同的参数数量,如下面的构造方法中,多添加了一个参数$age。

 代码如下 复制代码

 <?php 

      class Student extends Person{ 

                                                

           public $name;     
          public $age;         
                                                

           public function __construct($name="",$age=25){ 
                $this->name =$name; 

                $this->age =$age; 

          } 

          public  function say(){ 

                echo "我叫".$this->name .",今年".$this->age."岁了" ;   

           }  
                                                   

 } 
 ?>

构造函数重写

上面提到的“重写时的参数数量”就已经实现了子类对父类的构造函数进行了重写,但这不是一种好的写    法,如果仔细观察,你会发现,上面子类Student对父类Person构造函数的重写,其实就是在父类的构造    函数的基础上多添加了一个参数,但是又把父类原有的参数照写一遍,因为父类Person的构造函数只有一    个参数,所以我们照写一遍不觉得有什么麻烦,但是如果参数不止一个,而是几个或者更多,那么你就会    发现它的繁琐之处,那么有没有办法可以简化这个问题呢?答案是肯定的,可通过使用"parent::方法名"    在子类的重载方法中调用父类中被它覆盖的方法。如使用"parent::__construct()"调用父类中被覆盖的    构造方法,其它方法的类似,于是上面的代码可以简化为:

 代码如下 复制代码

 <?php 

      class Student extends Person{ 

                                      

           public $name;     

           public $age;         
                                     
          public function __construct($name="",$age=25){ 

              parent::__construct($name,$age); 

              $this->age =$age; 
         } 

           public  function say(){ 
             parent::say(); 

              echo ",今年".$this->age."岁了" ;   

          }  
                                         
 } 
 ?>

下再看一个实例

PHP5重写方法
先设置一个父类,这个父类是 “Dog”类,这个类描述了dog的特性。

Dog有2个眼睛,会跑,会叫。就这样描述先。

我养了一直狗,是只小狗,符合Dog类的特性,但有所不同。

我的小狗有名字,我的小狗太小了,不会大声的叫,只会哼哼。

我们用继承的概念去实现这个设计。

 代码如下 复制代码

<?
// 狗有两只眼睛,会汪汪叫,会跑.
class  Dog {
 protected  $eyeNumber =2; //属性
 //返回封装属性的方法.
 public function getEyeNumber(){
  return $this->eyeNumber;
 }
 //狗会叫 
 public function  yaff(){
  return  "Dog yaff, wang ..wang ..";
 }
 //狗会跑
 public function  run(){
  return  "Dog run..running ...";
 }
}
$dog = new Dog();
echo "dog have ".$dog->getEyeNumber()." eyes. <br>";
echo $dog->yaff() ."<br>".$dog->run();
echo  "<br><br>";
//这是我的小狗叫"狗狗",它很小.不会汪汪叫,只会哼哼哼..
class MyDog extends Dog {
 private $name = "狗狗";
 public function getName(){
  return $this->name;
 }
    public function  yaff(){
  return  $this->name." yaff, heng...heng ..";
 } 
}
$myDog = new MyDog();
echo $myDog->getName()." have ".$myDog->getEyeNumber()." eyes. <br>";
echo $myDog->yaff() ."<br>".$myDog->run();
?>

程序运行结果:

dog have 2 eyes.
Dog yaff, wang ..wang ..
Dog run..running ...

狗狗 have 2 eyes.
狗狗 yaff, heng...heng ..
Dog run..running ...

重写方法与访问权限
子类中的覆盖方法不能使用比父类中被覆盖方法更严格的访问权限。

父类为public 子类为 private时。

 代码如下 复制代码

<?
// 简化dog类和mydog类,演示重写的访问权限.
class Dog {
 protected  $eyeNumber =2; //属性
 //返回封装属性的方法.
 public function getEyeNumber(){
  return $this->eyeNumber;
 } 
}

class MyDog extends Dog {
 protected function getEyeNumber(){
  return $this->eyeNumber;
 } 
}
/*
class MyDog extends Dog {
 private function getEyeNumber(){
  return $this->eyeNumber;
 } 
}
*/

?>

程序运行结果:
 Fatal error: Access level to MyDog::getEyeNumber() must be public (as in class Dog) in E:PHPProjectstest.php on line 15

父类为public 子类为 protected时。

 

 代码如下 复制代码

<?
// 简化dog类和mydog类,演示重写的访问权限.
class Dog {
 protected  $eyeNumber =2; //属性
 //返回封装属性的方法.
 public function getEyeNumber(){
  return $this->eyeNumber;
 } 
}

class MyDog extends Dog {
 private function getEyeNumber(){
  return $this->eyeNumber;
 } 
}

?>

程序运行结果:

 Fatal error: Access level to MyDog::getEyeNumber() must be public (as in class Dog) in E:PHPProjectstest.php on line 15

重写时的参数数量
子类可以拥有与父类不同的参数数量。(这点与java不同,PHP是弱类型语言。)

 代码如下 复制代码


<?
// 简化dog类和mydog类,演示重写方法的参数.
class  Dog {
 protected  $eyeNumber =2; //属性
 //返回封装属性的方法.
 public function getEyeNumber(){
  return $this->eyeNumber;
 } 
}
class MyDog extends Dog {
 //重写的方法与父类的方法有不同的参数数量.
 public function getEyeNumber($eys){
  $this->eyeNumber = $eys;
  return $this->eyeNumber;
 } 
}

$myDog = new MyDog();
echo "my dog hava ".$myDog->getEyeNumber(3) ." eyes.";
//啸天犬..哈..
//下面这句会报一个丢失参数的错误.
//echo "my dog hava ".$myDog->getEyeNumber() ." eyes.";
?>

程序运行结果:

 my dog hava 3 eyes.

构造函数重写

下面这个例子中,父类和子类都有自己的构造函数,当子类被实例化时,子类的构造函数被调用,而父类的构造函数没有被调用,请对比第一节的构造函数继承。

 

 代码如下 复制代码

<?
//2-2 / extends1.php
//构造函数继承的问题.
class Animal{
 public $legNum = 0;
 public function __construct(){
  $this->legNum = 4;
  echo "I am an animal<br>";
 }
}
class Dog1 extends Animal {
 public function __construct(){
  $this->legNum = 4;
  echo "I am a Dog .<br>";
 }
}
$dog1 = new Dog1();
echo "<br>";
echo  "legNum is ".$dog1->legNum;
/*
实例化子类时.构造函数被调用了.
*/
?>

程序运行结果:

 I am a Dog . 
legNum is 4

注:这点和Java不同,在java中构造函数是不能被继承的,而且子类实例化时,子类的构造函数被调用,父类的构造函数也会调用。

在php中static是一个静态变量,他可以定义函数,变量为全局静态变量了,那么我们在函数或变量前面加上static会对函数与变量产生怎么样的影响呢,下面我们一起来看看。

 
1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。

2) 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。  

3) static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件


PHP5.3.0之后,我们可以用一个变量来动态调用类。但该变量的值不能为关键字self, parent 或static。

Example #1 静态成员代码示例

 代码如下 复制代码


<?php
class Foo
{
    public static $my_static = 'foo';

    public function staticValue() {
        return self::$my_static;
    }
}

class Bar extends Foo
{
    public function fooStatic() {
        return parent::$my_static;
    }
}


print Foo::$my_static . " ";

$foo = new Foo();
print $foo->staticValue() . " ";
print $foo->my_static . " ";      // Undefined "Property" my_static

print $foo::$my_static . " ";
$classname = 'Foo';
print $classname::$my_static . " "; // PHP 5.3.0之后可以动态调用

print Bar::$my_static . " ";
$bar = new Bar();
print $bar->fooStatic() . " ";
?>

 Example #2 静态方法代码示例

<?php
class Foo {
    public static function aStaticMethod() {
        // ...
    }
}

Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // As of PHP 5.3.0
?>

关于Static关键字在类中的使用,PHP手册给出了如下的约定:


1、声明类成员或方法为static,就可以不实例化类而直接访问。不能通过一个对象来访问其中的静态成员(静态方法除外)。

2、由于静态方法不需要通过对象即可调用,所以伪变量$this在静态方法中不可用。
3、静态属性不可以由对象通过->操作符来访问。
4、用::方式调用一个非静态方法会导致一个E_STRICT级别的错误。
现在来关注一下第4条约定。
运行环境: (Win32) PHP/5.3.3

 代码如下 复制代码

class Foo{ 
    
    public static $my_static = 'foo';//声明一个静态成员 
    
    
    public function staticValue() {//静态方法 
        return self::$my_static;// 
    } 
    public function run(){//非静态方法 
      return "abc <br>"; 
    } 
    public  function callrun() { 
        return self::run();//用self::方式调用一个非静态方法 
            
    } 
     

    
echo Foo::$my_static . "<br >"; 
    
echo Foo::run();//用className::方法名调用非静态方法 
echo Foo::callrun();

面试题之static关键字


题目代码:写出以下代码的运算结果( )

 代码如下 复制代码

<?php

function dewen(){
  $k=add_number(100);
  $k+=add_number(100);
  printf("%d",$k);
  return 0;
 }

 function add_number($n){
  static $i=100;
  $i+=$n;
  return $i;
 }

第一眼以为就是简单地自加计算:以为结果是400,结果答案错误。最后仔细看了下,敲了一边代码,运行才知道是500。打印了两次$i+=$n;计算之前的$i,一次是100,一次是200;知道问题是static在做鬼。然后百度了一下static关键字,才恍然大悟。

static关键字作用:

PHP中static变量的使用范围要更广一些,我们不仅可以在类,方法或变量前面添加 static修饰符,我们甚至还能给函数内部变量添加static关键字。添加了static修饰符的变量即使在该函数执行完毕值仍然不会丢失,也就是说,在下一次调用这个函数时,变量仍然记得原来的值。如:

 代码如下 复制代码

01  <?php 

02  function test() 

03  { 

04       static $var1 =1; 

05       $var1 +=2; 

06       echo $var1 . ' ' ; 

07  } 

08   

09  test(); 

10  test(); 

11  test(); 

12  ?> 
运行结果如下:

3 5 7

综上所述:

static全局变量与普通的全局变量有什么区别:
static全局变量只初使化一次,防止在其他文件单元中被引用;   
static局部变量和普通局部变量有什么区别:
static局部变量只被初始化一次,下一次依据上一次结果值;   
static函数与普通函数有什么区别:
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

利用php实例登入登出我们一般会借助于session来保存记录用户登录成功的信息,然后退出时我们再使用unset来清除session即可实现用户登入登出功能了,下面我来介绍一个简单的实例。

关于会话处理

HTTP 是一种无状态的协议,说明每次请求的处理都与之前或之后的 请求无关,但是为了能够调整用户特有的行为和首选项,出现了一种在客户端存储少量信息(常称为cookie)的实践,但由于 cookie 大小的限制、所允许的 cookie 数量以及 cookie 的实现上的各种不一致,出现了另外一种解决方案:会话处理。

会话处理的实现方式是为每位网站访问者分配一个称之为会话 ID(SID)的唯一标识属性,然后将此 SID 与任意数量的数据关联。

开始会话

session_start();

创建会话变量

 代码如下 复制代码

$_SESSION['username'] = “jason”;

删除会话变量

 代码如下 复制代码
unset($_SESSION['username']);

简单的登入登出

 代码如下 复制代码

$supervisor = "admin";
$superpsw = "passwd";

// 检查是否提交表单
if (isset($_POST['superadmin']))
{
if (!($_POST['supername'] == $supervisor) || !($_POST['superpass'] == $superpsw))
{
echo "用户名或密码错误";
exit;
}
else
{
session_start();
$_SESSION["superlogin"] = $_POST['supername'];
}
} else {
session_start();
// 检查是否设置了会话变量,即是否已经登入,如果没有,显示登入页面
if (! isset($_SESSION["superlogin"]) )
{
echo "<form name='form1' method='post' action='$_SERVER[PHP_SELF]'>";
echo "<div align='center'>请输入管理员密码<br />";
echo "管理员";
echo "<input type='text' name='supername'><br />";
echo "密  码";
echo "<input type='password' name='superpass'><br />";
echo "<input type='submit' name='superadmin' value='进入'><br />";
echo "<input type='reset' name='cancel' value='重写'></div>";
echo "</form>";
exit;
}
}
// 由用户销毁会话变量,登出
if (isset($_GET['logout'])) {
unset($_SESSION['superlogin']);
header("Location:index.php");
}

假设将此文件命名为include.php,将其包含到要验证登入的页面即可,例如 index.php

 代码如下 复制代码

    <?php
    require “include.php”;
    ?>
    <html>
    <head>
    <title>管理</title>
    <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>
    </head>
    <body>
    <p><a href=”index.php?logout=1″>登出</a>
    <p>欢迎进入</p>
    </body>
    </html>

如此访问 index.php 页面时将进入登入页面,登录后显示 index.php 页面内容,这个过程一直持续到用户结束会话,如关闭浏览器或点击注销按钮,但是会话本身在PHP服务器有一个默认的生存期。

有效会话的持续时间由 php.ini 所控制,默认为1440秒,即24分钟

    session.gc_maxlifetime = 1440

PS:本文是个范例,用简单的代码来做说明,实际应用中会采用更加复杂的控制机制。

本文章来给各位同学介绍一下关于php 浮点数精度值实例程序详解,希望有需要理解浮点数精度值的朋友可进入参考。

php中浮点数的精度值是用来控制输出该浮点数时使用的,可以理解为控制输出的位数,精度值不同,看到输出结果也可能不一样,注意:其内部还是按照实际值存储的,当两个浮点数进行四则运算时,用的还是其本来的值。

php的配置文件中使用precision来设定全局指定浮点数的精度值,似乎每个发行版,它的默认设置都不太一样,我在window下看到是12,在linux下看到此值是14,当然也可以通过程序中使用ini_set来改变全局设置,例如:

 代码如下 复制代码
 ini_set("precision", "15");

对于精度我一直理解为小数点后保留多少,那么在php的浮点数中是这样的么?答案是否定的。

浮点数其实是整数部分和小数部分组成,这里的精度是指整数部分的位数加小数部分的位数不能超过其精度最大值,如果超过,则按照四舍五入的方法截断到最大的精度值。整数部分如果是0,则不计位数,小数部分末尾0也不计入位数。另外对于同一个数,precision的不同,可能显示的出来表现形式也不一样。下面通过例子的方式来说明。

整数部分为 0 情况

 

 代码如下 复制代码

$num = 0.12345600000000000;
 //整数部分为0 ,位数为 0 ,小数部分末尾的 0 不计入位数,所以总位数为 6

 ini_set("precision", "12");
 echo $num; // 0.123456
 //未超过精度值,显示的结果为 0.123456

 ini_set("precision", "3");
 echo $num; // 0.123
 //超过精度值,保留3位

 ini_set("precision", "5");
 echo $num; // 0.12346

 //超过精度值,保留5位这种情况下,精度值等价于小数点后保留几位。

整数部分大于 0 情况

 代码如下 复制代码

 $num = 12.12345600000000000;
 //整数部分为12 ,位数为 2 ,小数部分末尾的 0 不计入位数,位数为6,所以总位数为 2 + 6

 ini_set("precision", "12");
 echo $num; // 12.123456
 //未超过精度值,显示的结果为 12.123456

 ini_set("precision", "3");
 echo $num; // 12.1
 //超过精度值,整数部分位数为 2 ,所以只保留一位小数

 ini_set("precision", "5");
 echo $num; // 12.123
 //超过精度值,整数部分位数为 2 ,所以只保留3位小数可以看到小数点后保留的位数跟精度已经整数部分的位数有关

整数部分大于 0 情况 之二

 代码如下 复制代码

 $num = 12345678.12345600000000000;
 //整数部分为12345678 ,位数为 8 ,小数部分末尾的 0 不计入位数,位数为6,所以总位数为 8 + 6

 ini_set("precision", "12");
 echo $num; // 12345678.1235
 //超过精度值,显示的结果为 12345678.1235

 ini_set("precision", "3");
 echo $num; // 1.23E+7
 //超过精度值,且整数部分位数超过精度,小数部分舍弃,且整数部分只取3位

 ini_set("precision", "5");
 echo $num; // 12346000

 //超过精度值,且整数部分位数超过精度,小数部分舍弃,且整数部分只取5位上述例子中可以看到,精度值也关系到整数部分的截取。注意到最后两个例子中显示的方式不一样,一个是使用科学计数法,一个是后面用 0 补。通过实验得出的结论是当整数部分的位数 减去 精度值 大于 4 的时候,使用科学计数法的方式,否则后面用 0 补,换句话说,就是整数部分位数超过精度值后,截断后,补 0 的个数不会超过 4 。

浮点数运算

 代码如下 复制代码

 $num1 = 1331625729.687;
 $num2 = 1331625730.934;
 ini_set("precision", "8");

 echo $num1 . '
';
 echo $num2 . '
';

 $sub = $num1 - $num2;

 echo $sub . '
';
//输出的结果为:
/*
 1331625700
 1331625700
 -1.247
*/

上述例子就说明了精度值只是控制显示结果,内部存储还是原始值,所以 $sub 的值为1331625729.687减1331625730.934。

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将浮点数转成字符串.

[!--infotagslink--]

相关文章

  • php正确禁用eval函数与误区介绍

    eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
  • php中eval()函数操作数组的方法

    在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • 微信小程序 页面传值详解

    这篇文章主要介绍了微信小程序 页面传值详解的相关资料,需要的朋友可以参考下...2017-03-13
  • 金额阿拉伯数字转换为中文的自定义函数

    CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • PHP函数分享之curl方式取得数据、模拟登陆、POST数据

    废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
  • PHP函数strip_tags的一个bug浅析

    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加密解密函数详解

    分享一个PHP加密解密的函数,此函数实现了对部分变量值的加密的功能。 加密代码如下: /* *功能:对字符串进行加密处理 *参数一:需要加密的内容 *参数二:密钥 */ function passport_encrypt($str,$key){ //加密函数 srand(...2015-10-30
  • php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法

    最近遇到一个问题,就是在使用php的mail函数发送utf-8编码的中文邮件时标题出现乱码现象,而邮件正文却是正确的。最初以为是页面编码的问题,发现页面编码utf-8没有问题啊,找了半天原因,最后找到了问题所在。 1.使用 PEAR 的...2015-10-21
  • C#中加载dll并调用其函数的实现方法

    下面小编就为大家带来一篇C#中加载dll并调用其函数的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#虚函数用法实例分析

    这篇文章主要介绍了C#虚函数用法,实例分析了C#中虚函数的功能与基本使用技巧,需要的朋友可以参考下...2020-06-25