首页 > 编程技术 > php

PHP浮点数转换整型注意事项

发布时间:2016-11-25 14:58

PHP浮点数是否有小数了,我们要转换整理可能会丢失小数位数据了,下面我来给大家介绍PHP浮点数转换整型的一些事项,有兴趣的同学可进入参考。

先我们来做个实验说明问题的存在

 代码如下 复制代码

$f = 0.58;
var_dump(intval($f * 100.0));

也许你认为他会输出58,但是实际上他输出的是57.
原因是作为浮点型数据,其精度已经损失了一部分,达不到完全精确。所以永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。

在实际的开发中我们可以使用如下逻辑来解决这种境况

 代码如下 复制代码

intval(round(floatval($value) * 100));

round也可以使用ceil目的就是将精度调准。

最近在学php,用php写个简单99乘法表,用到for循环,其实这个也可以改下放shell中,下面来看两个例子有兴趣的朋友可进入参考。

for 语句
如果您已经确定了代码块的重复执行次数,则可以使用 for 语句。

语法

PHP

 代码如下 复制代码
for (initialization; condition; increment)
{
  code to be executed;
}

注释:for 语句有三个参数。第一个参数初始化变量,第二个参数保存条件,第三个参数包含执行循环所需的增量。如果 initialization 或 increment 参数中包括了多个变量,需要用逗号进行分隔。而条件必须计算为 true 或者 false。

例子
下面的例子会把文本 “Hello World!” 显示 5 次:

PHP

 代码如下 复制代码

<html>
<body>
 
<?php
for ($i=1; $i<=5; $i++)
{
  echo "Hello World!<br />";
}
?>
 
</body>
</html>

下面再看看99乘法表这个的正序写法,要用到嵌套循环。

 

 代码如下 复制代码
<?php
/**
99乘法表正序
**/
for ($i=1;$i<=9;$i++)
{
    echo "<br>";                   
    for ($n=1;$n<=9;$n++)
    {       
            if ($i >= $n)
                {               
                echo "$i*$n".'='.$i*$n;               
                echo "&nbsp";               
                }
    }
}
?>

运行这个php得到的结果 :

php版99乘法口诀表

下面想让这个乘法表倒序,其实只有for循环里面数字逐渐递减就可以。

 代码如下 复制代码

<?php
/**
99乘法表倒序
**/
for ($i=9;$i>=1;$i--)
{
    echo "<br>";                   
    for ($n=9;$n>=1;$n--)
    {       
            if ($i >= $n)
                {               
                echo "$i*$n".'='.$i*$n;               
                echo "&nbsp";               
                }
    }
}
?>

倒序显示如下:

php简单显示99乘法表

在php中传值与传引用对于我们来讲是有比较大的区别的一个引用可以调用内存地址赋值了,这样只要内存地址中内容变化而赋值的变量也就变化了,付值只是把内存中值给其它变量而己。

传值:  

函数参数压栈的是参数的副本。  

任何的修改是在副本上作用,没有作用在原来的变量上。  

传引用:
  
压栈的是引用的副本。由于引用是指向某个变量的,对引用的操作其实就是对他指向的变量的操作。(作用和传指针一样,只是引用少了解指针的草纸) 

例子

 代码如下 复制代码

function func1($a) { $a = $a + 1;}
function func2(&$a) { $a = $a + 1;}
 $sample = 1;
func1($sample);
 echo $sample; // 输出 1
 $sample = 1;
func2($sample);
 echo $sample; // 输出 2

例子

 代码如下 复制代码


<?php
$num1 = 15;
$num2 = &$num1;
$num2 = 20;
echo $num1;//输出20
?>

再比如:

 代码如下 复制代码

<?php
function func1($a) {
  $a = $a + 1;
}
function func2(&$a) {
  $a = $a + 1;
}
$sample = 1;
func1($sample);
echo $sample; // 输出 1
 
$sample = 1;
func2($sample);
echo $sample; // 输出 2
<?>

总结一下

传值的话,如果是非对象,会传一个值的拷贝,对这个变量做任何改动都不影响原值。传引用或者传对象,是传真实的内存地址,对这个变量做的改动会影响原值。

在php中PHP构造函数是一个提高工作性能的不作做法了,它可以实现自动构造与自动处理一些变量或执行指定函数了,下面给大家全部的介绍了构造函数的用法。

构造函数用法

HP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。

Note: 如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。
Example #1 使用新标准的构造函数

 代码如下 复制代码

<?php
class BaseClass {
   function __construct() {
       print "In BaseClass constructorn";
   }
}

class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();
       print "In SubClass constructorn";
   }
}

class OtherSubClass extends BaseClass {
    // inherits BaseClass's constructor
}

// In BaseClass constructor
$obj = new BaseClass();

// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();

// In BaseClass constructor
$obj = new OtherSubClass();
?>

为了实现向后兼容性,如果 PHP 5 在类中找不到 __construct() 函数并且也没有从父类继承一个的话,它就会尝试寻找旧式的构造函数,也就是和类同名的函数。因此唯一会产生兼容性问题的情况是:类中已有一个名为 __construct() 的方法却被用于其它用途时。

与其它方法不同,当 __construct() 被与父类 __construct() 具有不同参数的方法覆盖时,PHP 不会产生一个 E_STRICT 错误信息。

自 PHP 5.3.3 起,在命名空间中,与类名同名的方法不再作为构造函数。这一改变不影响不在命名空间中的类。

Example #2 Constructors in namespaced classes

 代码如下 复制代码

<?php
namespace Foo;
class Bar {
    public function Bar() {
        // treated as constructor in PHP 5.3.0-5.3.2
        // treated as regular method as of PHP 5.3.3
    }
}
?>

建对象的时候赋初值。

 代码如下 复制代码
1. //创建一个人类 
2. 
3. 0class Person  
4. 0{  
5. //下面是人的成员属性  
6. var $name;       //人的名子  
7. var $sex;        //人的性别  
8. var $age;        //人的年龄  
9. //定义一个构造方法参数为姓名$name、性别$sex和年龄$age  
10. function __construct($name, $sex, $age)  
11. {  
12. //通过构造方法传进来的$name给成员属性$this->name赋初使值  
13. $this->name=$name;  
14. //通过构造方法传进来的$sex给成员属性$this->sex赋初使值  
15. $this->sex=$sex;  
16. //通过构造方法传进来的$age给成员属性$this->age赋初使值  
17. $this->age=$age;  
18. }  
19. //这个人的说话方法  
20. function say()  
21. { 
22. echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";  
23. }  
24. }  
25. //通过构造方法创建3个对象$p1、p2、$p3,分别传入三个不同的实参为姓名、性别和年龄 
26. $p1=new Person("张三","男", 20);  
27. $p2=new Person("李四","女", 30);  
28. $p3=new Person("王五","男", 40);  
29. //下面访问$p1对象中的说话方法  
30. $p1->say();  
31. //下面访问$p2对象中的说话方法  
32. $p2->say();  
33. //下面访问$p3对象中的说话方法  
34. $p3->say(); 

 
输出结果为:

我的名子叫:张三性别:男我的年龄是:20
我的名子叫:李四性别:女我的年龄是:30
我的名子叫:王五性别:男我的年龄是:40

构造函数的继承问题

先来看一个简单的例子:

 代码如下 复制代码


<?php

class Fruit {

public function __construct($name)

{

echo '水果'.$name.'创建了';

}

}

 

class Apple extends Fruit {

public function __construct($name)

{

parent::__construct($name);

}

}

 

$apple = new Apple("苹果");

 

// 输出 水果苹果创建了

?>

构造函数的继承节省的是代码的重写,而不是方法的声明,也就是说,在父类中声明的构造函数必须再在子类中声明一次,其实,这也是一个重写的过程。

PHP的构造函数继承必须满足以下条件:

当父类有构造函数的声明时,子类也必须有声明,否则会出错。
在执行父类的构造函数时,必须在子类中引用parent关键字。
如果父类有构造函数,而且子类没有构造函数,那么在子类实例化时确实会执行父类构造函数。例如,假设Employee类有如下构造函数:

 

 代码如下 复制代码

function  __construct($name){

$this->setName($name);

}
然后实例化CEO类,获得其name成员:


$ceo= new CEO("Gonn");

echo $ceo->getName();
将得到如下结果:


My name is Gonn

但是,如果子类也有构造函数,那么当子类实例化时,不论父类是否有构造函数,都会执行子类自己的构造函数。例如,假设除了Employee类包含上述构造函数外,CEO类也包含如下构造函数:

 

 代码如下 复制代码

function  __construct(){

echo "CEO object created!";

}

再来实例化CEO类,以同样的方式执行getName(),这次将得到不同的输出:


CEO object created!

My name is Gonn
当遇到parent::__construct()时,PHP开始沿着父类向上搜索合适的构造函数。因为在Executive中没有找到,所以继续搜索知道Employee类,在这里找到了合适的构造函数。如果PHP在Employee类中找到构造函数,就会执行这个构造函数。如果希望既执行Employee构造函数,又执行Executive构造函数,则需要在Executive构造函数中调用parent::__construct()。

此外,还可以选择另一种方式来引用父类的构造函数。例如,假设创建新的CEO对象时,Employee和Executive的构造函数都要执行。如上述,可以在CEO的构造函数中显示地引用这些构造函数,如下:

 代码如下 复制代码


function __construct($name){

Employee::__constrcut($name);

Executive::__construct();

echo "CEO object created!";
}

不同php版本中构造函数继承

构造函数中的引用


  PHP 4.x 的构造函数名与类名相同。
子类的构造函数名与子类名相同(废话)。
在子类里父类的构造函数不会自动执行。
要在子类里执行父类的构造函数,必须执行类似以下语句:
  $this->[父类的构造函数名()]

例如:

 代码如下 复制代码

class base1
{
  function base1()
  {
echo 'this is base1 construct';
  }
}

class class1 extends base1
{
  function class1()
  {
$this->base1();
echo 'this is class1 construct';
  }
}
$c1 = new class1;

PHP5.x 版本:

PHP5.0 以上版本对类的功能进行了很大的扩充。类的构造函数统一命名为__construct()。
子类的构造函数名也是__construct()(也是废话)。
在子类里父类的构造函数会不会执行,分两种情况:
1,如子类不定义构造函数 __construct(),则父类的构造函数默认会被继承下来,且会自动执行。
2,如子类定义了构造函数 __construct(),因为构造函数名也是__construct(),所以子类的构造函数实际上是覆盖(override)了父类的构造函数。这时执行的是该子类的构造函数。
   这时如果要在子类里执行父类的构造函数,必须执行类似以下语句:

parent::__construct();

例如:

 代码如下 复制代码

class base2
{
  function __construct()
  {
echo 'this is base2 construct';
  }
  function __destruct()
  {
  }
}

class class2 extends base2
{
  function __construct()
  {
parent::__construct();
echo 'this is class2 construct';
  }
}

注意 parent::__construct(); 语句不一定必须放在子类的构造函数中。放在子类的构造函数中仅仅保证了其在子类被实例化时自动执行。

PHP4.0 和 5.0 类构造函数的兼容问题:

在 PHP5.0 以上版本里,还兼容了 4.0 版本的构造函数的定义规则。如果同时定义了4.0的构造函数和 __construct()函数,则__construct() 函数优先。
为了使类代码同时兼容 PHP4.0 和 5.0,可以采取以下的方式:

 代码如下 复制代码

class class3
{
  function __construct() //for PHP5.0
  {
echo 'this is class2 construct';
  }

  function class3() //for PHP4.0
  {
$this->__construct();
  }
}

$c3 = new class3;

php构造函数中的引用的内容。

 代码如下 复制代码
<?php
class Foo {
   function Foo($name) {
    
       global $globalref;
       $globalref[] = &$this;
 
       $this->setName($name);
     
       $this->echoName();
   }
   function echoName() {
       echo "<br />",$this->name;
   }
   function setName($name) {
       $this->name = $name;
   }
}
?>

下面来检查一下用拷贝运算符 = 创建的 $bar1 和用引用运算符 =& 创建的 $bar2 有没有区别...
copy to clipboard
显然没有区别,但实际上有一个非常重要的区别:$bar1 和 $globalref[0] 并没有被引用,它们不是同一个变量。这是因为“new”默认并不返回引用,而返回一个拷贝。

 代码如下 复制代码
<?php
$bar1 = new Foo('set in constructor');
$bar1->echoName();
$globalref[0]->echoName();
/* &#36755;&#20986;&#65306;
set in constructor
set in constructor
set in constructor */
$bar2 =& new Foo('set in constructor');
$bar2->echoName();
$globalref[1]->echoName();
/* &#36755;&#20986;&#65306;
set in constructor
set in constructor
set in constructor */
?>

 

下面我们一起来看看nginx与PHP的SERVER_NAME和HTTP_HOST详解,希望文章对各位会有所帮助

ERVER_NAME对应Nginx配置文件中的server_name,通过fastcgi_param设置,如域名指向到IP而不在nginx中设置对应的server_name,PHP取SERVER_NAME为空,如果有多个server_name,取第一个。

例子

 代码如下 复制代码

server_name   www.111cn.net;
fastcgi_param  SERVER_NAME        $server_name;

HTTP_HOST包含在HTTP请求信息中,即请求的域名或IP,Nginx内为host。

HTTP_HOST 和 SERVER_NAME 的区别:

一:相同时满足以下三个条件:

1.服务器端口默认80

2.apache或nginx中ServerName设置正确
3.HTTP/1.1协议规范

二:不同点:

$_SERVER['HTTP_HOST']会根据客户端HTTP请求输出信息
$_SERVER['SERVER_NANE']会根据apache或nginx的配置文件中的ServerName值

当端口不为80时
$_SERVER['HTTP_HOST']输出中会带有端口号
$_SERVER['SERVER_NAME']只会直接输出ServerName的值

所以,应尽量使用$_SERVER["HTTP_HOST"],保险,可靠!

标签:[!--infotagslink--]

您可能感兴趣的文章: