PHP构造函数的继承分析

 更新时间:2016年11月25日 14:58  点击:1892
在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 */
?>

 

在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
<?>

总结一下

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

下面我们一起来看看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"],保险,可靠!

在php中上传图片我们全结合$_files 与move_uploaded_file函数来一起操作,从而实现从客户端把文件上传到服务器端了,下面一起来看看具体的操作子。

编程环境

PHP5.2.4,基本上PHP4.3以上版本,此代码都可以使用

准备工作

检查upload_tmp_dir项

如果PHP的开发环境是自行搭建的,你需要在编写文件上传程序前编辑php.ini文件,找到并编辑upload_tmp_dir选项,此项用来设定文件上传至服务器时的临时文件夹,比如upload_tmp_dir = E:/phpos/uploads,然后再重启Apache。如果PHP的开发环境使用的是傻瓜式一键安装包,一般upload_tmp_dir都是设定好了的,你也可以用phpinfo()函数查看下配置

html

 代码如下 复制代码
<input name="userfile" type="file">

示例:

 代码如下 复制代码

if (! empty ( $_FILES ['file'] ['name'] )) {
 $img = $this->up_file ( "file" );
}

up_file()函数:

 代码如下 复制代码

function up_file($inputname, $destinate = "../data/agency/", $type = "", $maxSize = 0) {
 $arr = explode ( '.', $_FILES [$inputname] ['name'] );
 $count = count ( $arr );
 $typearr = explode ( ',', $type );
 
 if (! empty ( $type )) {
  if (! in_array ( $arr [$count - 1], $typearr )) {
   $this->show_warning ( '文件类型不允许上传' );
   exit ();
  }
 }
 if ($maxSize != 0) {
  if (($_FILES [$inputname] ['size'] / 1000) >= $maxSize) {
   $this->show_warning ( '文件大小超过限制' );
   exit ();
  }
 }
 
 if (! empty ( $destinate )) {
  $destinate = substr ( str_replace ( "", "/", $destinate ), - 1 ) == "/" ? $destinate : $destinate . "/";
  if (! is_writable ( $destinate )) {
   $this->show_warning ( '文件目录发生错误' );
   exit ();
  }
 }
 $filename = date ( "YmdHis" ) . (microtime () * 1000000) . "." . $arr [$count - 1];
 
 if (is_file ( $destinate . $filename )) {
  up_file ( $inputname, $destinate = "", $type = "", $maxSize = 0 );
 } else {
  $filename = $filename;
 }
 copy ( $_FILES [$inputname] ['tmp_name'], $destinate . $filename );
 @unlink ( $_FILES [$inputname] ['tmp_name'] );
 return $filename;
}

以上范例中 $_FILES 数组的内容如下所示。我们假设文件上传字段的名称为 userfile(名称可随意命名)
如何上传多个文件?比如同时上传3个文件

只需将

 代码如下 复制代码


<input name="userfile" type="file">
改成

<input name="userfile[]" type="file">
<input name="userfile[]" type="file">
<input name="userfile[]" type="file">

对应的在调用此函数时,$_FILES['userfile']['name'][0],代表第一个文件的相关文件信息,依此类推,其他也一样。

$_FILES['userfile']['name'] 客户端机器文件的原名称。
 $_FILES['userfile']['type'] 文件的 MIME 类型,需要浏览器提供该信息的支持,例如“image/gif”。
 $_FILES['userfile']['size'] 已上传文件的大小,单位为字节。
 $_FILES['userfile']['tmp_name'] 文件被上传后在服务端储存的临时文件名。
 $_FILES['userfile']['error'] 和该文件上传相关的错误代码

值:0; 没有错误发生,文件上传成功。
 值:1; 上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。
 值:2; 上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
 值:3; 文件只有部分被上传。
 值:4; 没有文件被上传。

上传大文件失败的解决办法

文件上传时存放文件的临时目录必须是开启的并且是 PHP 进程所有者用户可写的目录。如果未指定则 PHP 使用系统默认值。

max_execution_time = 90
file_uploads = On
upload_max_filesize = 2M 设定文件上传的大小的最大值

在php中会为我们提供一些常用的字符操作函数,下面我来整理了php中字符大小字转换的函数,这里我会一个个介绍,希望例子能给各位同学带来帮助。

每个单词的首字母转换为大写: ucwords()
第一个单词首字母变大写: ucfirst()
第一个单词首字母变小写: lcfirst()
所有 字母变大写: strtoupper()

例子

 代码如下 复制代码

<?php
echo strtoupper("Hello WORLD!");
?>

输出:

HELLO WORLD!

第一个单词首字母变大写:ucfirst()

 代码如下 复制代码

<?php
$foo = 'where are doing?!';
$foo = ucfirst($foo);             // where are doing?!

$bar = 'where are doing?!';
$bar = ucfirst($bar);             // where are doing?!
$bar = ucfirst(strtolower($bar)); // where are doing?!
?>

所有 字母变小写: strtolower()

 代码如下 复制代码

<?php
$str = "Mary Had A Little Lamb and She LOVED It So";
$str = strtolower($str);
echo $str; // Prints mary had a little lamb and she loved it so
?>


每个单词的首字母转换为大写:ucwords()

 代码如下 复制代码

<?php
$foo = 'where are doing?!';
$foo = ucwords($foo);             // Where are doing?!

$bar = 'where are doing?!';
$bar = ucwords($bar);             // Where are doing?!
$bar = ucwords(strtolower($bar)); // Where are doing?!
?>

 
 
第一个单词首字母变小写:lcfirst()

 代码如下 复制代码

<?php
$foo = 'HelloWorld';
$foo = lcfirst($foo);             // where are doing

$bar = 'where are doing?!';
$bar = lcfirst($bar);             // where are doing?!
$bar = lcfirst(strtoupper($bar)); // where are doing?!
?>

[!--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
  • 金额阿拉伯数字转换为中文的自定义函数

    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
  • PHP编码转换函数mb_convert_encoding与iconv用法

    文章来实现一个PHP编码转换函数mb_convert_encoding与iconv用法,希望例子能帮助到各位。 将一个短信接口代码从apache迁移到nginx+php-fpm后,发现无法发出短信了,查...2016-11-25