技术的世界只说技术就好了..

分类目录

近期文章

标签

近期评论

功能

2018年八月
« 11月    
 12345
6789101112
13141516171819
20212223242526
2728293031  

关于Discuz!X1 嵌入点 及其插件的编写 注意说明

首先插件的路径改变了
插件放置于 source/plugin/目录下
数据库读取的写法也发生了改变:
使用了类的静态方法好处显而易见不需要原来 $GLOBALS[‘db’] 直接在任何地点拿出来就能用
DB::table('forum_attachment');   //这里会返回 pre_ forum_attachment
DB::fetch_first($query)              //这里对应原来DZ7的 $db->
fetch_first($query)
DB::query($query)                    //对应原来DZ7的 $db-> query ($query)
DB::fetch($query)                     //对应原来DZ7的 $db-> fetch ($query)
关于嵌入点:
Discuz!X1  由于有众多模块 .. 所以插件平台在原来DZ7.2 的基础上进行了升级
具体的写法:
class plugin_bigqi_com {
function plugin_bigqi_com(){
//这个写法会被插件执行函数runhooks() 运行时调用执行...
return 'this is globals plugin_bigqi_com';
}
function global_footer(){
// 这个是全局嵌入点的...所有的页面包括首页论坛群组空间等等
return 'this is globals global_footer';
}}
//下面这里就重要了..
// DISCUZ! X 的插件运行机制有些改动... 由于Dx 使用了模块化包含方式..
//所以就有必要强调嵌入点是哪个模块下的
//模块的定义在每个最外层文件的最上部如:forum.php
// define('CURSCRIPT', 'forum'); 定义了模块名称 forum
//另外原来DISCUZ 7.2 使用的执行脚本常量由原来的 CURSCRIPT 改为 CURMODULE
//所以大家在写 forum 嵌入点的时候判断模块下执行的脚本就要用 CURMODULE 来判断
//另外嵌入点的具体写法如下:
//只有用插件名+下横线+模块的名称对原来的类进行继承扩展才能让模块内的嵌入点显示
class plugin_bigqi_com_forum extends plugin_bigqi_com {
function index_top(){
return 'this is forum index_top';
}
}
// 另外 原来的 DZ7.2 使用的引用模板的写法不变只是插件的模板目录的名称改变了
由templates 改成了 template
例如:
source/plugin/bigqi_com_picrollshow/template/
插件模板引擎的写法 保持不变 我这里写个示例
// include template('bigqi_com:picrollshow');
// return $return;

首先插件的路径改变了
插件放置于 source/plugin/目录下
数据库读取的写法也发生了改变:
使用了类的静态方法好处显而易见不需要原来 $GLOBALS[‘db’] 直接在任何地点拿出来就能用
DB::table('forum_attachment');   //这里会返回 pre_ forum_attachmentDB::fetch_first($query)              //这里对应原来DZ7的 $db->fetch_first($query)DB::query($query)                    //对应原来DZ7的 $db-> query ($query)DB::fetch($query)                     //对应原来DZ7的 $db-> fetch ($query)
关于嵌入点:
Discuz!X1  由于有众多模块 .. 所以插件平台在原来DZ7.2 的基础上进行了升级
具体的写法:
class plugin_bigqi_com {         function plugin_bigqi_com(){                   //这个写法会被插件执行函数runhooks() 运行时调用执行...                   return 'this is globals plugin_bigqi_com';         }         function global_footer(){                   // 这个是全局嵌入点的...所有的页面包括首页论坛群组空间等等                   return 'this is globals global_footer';         }}
//下面这里就重要了..// DISCUZ! X 的插件运行机制有些改动... 由于Dx 使用了模块化包含方式..//所以就有必要强调嵌入点是哪个模块下的//模块的定义在每个最外层文件的最上部如:forum.php// define('CURSCRIPT', 'forum'); 定义了模块名称 forum//另外原来DISCUZ 7.2 使用的执行脚本常量由原来的 CURSCRIPT 改为 CURMODULE//所以大家在写 forum 嵌入点的时候判断模块下执行的脚本就要用 CURMODULE 来判断//另外嵌入点的具体写法如下://只有用插件名+下横线+模块的名称对原来的类进行继承扩展才能让模块内的嵌入点显示class plugin_bigqi_com_forum extends plugin_bigqi_com {         function index_top(){                   return 'this is forum index_top';         }
}
// 另外 原来的 DZ7.2 使用的引用模板的写法不变只是插件的模板目录的名称改变了由templates 改成了 template例如:source/plugin/bigqi_com_picrollshow/template/插件模板引擎的写法 保持不变 我这里写个示例// include template('bigqi_com:picrollshow');// return $return;

php socket模拟POST GET请求 fsockopen版

function httpRequestGET($url){
  $url2 = parse_url($url);
  $url2["path"] = ($url2["path"] == "" ? "/" : $url2["path"]);
  $url2["port"] = ($url2["port"] == "" ? 80 : $url2["port"]);
  $host_ip = @gethostbyname($url2["host"]);
  $fsock_timeout=20;
  if(($fsock = fsockopen($host_ip, 80, $errno, $errstr, $fsock_timeout)) < 0){
    return false;
  }
  
  $request =  $url2["path"] . ($url2["query"] != "" ? "?" . $url2["query"] : "") . ($url2["fragment"] != "" ? "#" . $url2["fragment"] : "");
  $in  = "GET " . $request . " HTTP/1.0\r\n";
  $in .= "Accept: */*\r\n";
  $in .= "User-Agent: Payb-Agent\r\n";
  $in .= "Host: " . $url2["host"] . "\r\n";
  $in .= "Connection: Close\r\n\r\n";
  if(!@fwrite($fsock, $in, strlen($in))){
    fclose($fsock);
    return false;
  }
  unset($in);
  
  $out = "";
  while($buff = @fgets($fsock, 2048)){
    $out .= $buff;
  }
  fclose($fsock);
  $pos = strpos($out, "\r\n\r\n");
  $head = substr($out, 0, $pos);    //http head
  $status = substr($head, 0, strpos($head, "\r\n"));    //http status line
  $body = substr($out, $pos + 4, strlen($out) - ($pos + 4));//page body
  if(preg_match("/^HTTP\/\d\.\d\s([\d]+)\s.*$/", $status, $matches)){
    if(intval($matches[1]) / 100 == 2){
      return $body;  
    }else{
      return false;
    }
  }else{
    return false;
  }
}
function httpRequestPOST($url,$post_data){
  $url2 = parse_url($url);
  $url2["path"] = ($url2["path"] == "" ? "/" : $url2["path"]);
  $url2["port"] = ($url2["port"] == "" ? 80 : $url2["port"]);
  $host_ip = @gethostbyname($url2["host"]);
  $fsock_timeout=20;//秒
  if(($fsock = fsockopen($host_ip, 80, $errno, $errstr, $fsock_timeout)) < 0){
    return false;
  }
  
  $request =  $url2["path"] . ($url2["query"] != "" ? "?" . $url2["query"] : "") . ($url2["fragment"] != "" ? "#" . $url2["fragment"] : "");
  
  $needChar = false;
  
  foreach($post_data as $key => $val)  {
    
    $post_data2 .= ($needChar ? "&" : "") . urlencode($key) . "=" . urlencode($val);
    $needChar = true;
  }
  $in  = "POST " . $request . " HTTP/1.0\r\n";
  $in .= "Accept: */*\r\n";
  $in .= "Host: " . $url2["host"] . "\r\n";
  $in .= "User-Agent: Lowell-Agent\r\n";
  $in .= "Content-type: application/x-www-form-urlencoded\r\n";
  $in .= "Content-Length: " . strlen($post_data2) . "\r\n";
  $in .= "Connection: Close\r\n\r\n";
  $in .= $post_data2 . "\r\n\r\n";
  
  unset($post_data2);
  if(!@fwrite($fsock, $in, strlen($in))){
    fclose($fsock);
    return false;
  }
  unset($in);
  
  $out = "";
  while($buff = fgets($fsock, 2048)){
    $out .= $buff;
  }
  
  fclose($fsock);
  $pos = strpos($out, "\r\n\r\n");
  $head = substr($out, 0, $pos);    //http head
  $status = substr($head, 0, strpos($head, "\r\n"));    //http status line
  $body = substr($out, $pos + 4, strlen($out) - ($pos + 4));//page body
  if(preg_match("/^HTTP\/\d\.\d\s([\d]+)\s.*$/", $status, $matches)){
    if(intval($matches[1]) / 100 == 2){
      return $body;
    }else{
      return false;
    }
  }else{
    return false;
  }
}

函数调用:
 

$post_data = array("name"=>"xd","sex"=>"man");
httpRequestPOST("http://localhost/post.php",$post_data);
 

socket写的顺序:
 

POST /post.php HTTP/1.0
Accept: */*
Host: localhost
User-Agent: Lowell-Agent
Content-type: application/x-www-form-urlencoded
Content-Length: 15
Connection: Close
name=xd&sex=man
 

普通POST的结果演示:
 

POST/?username=111&password=222HTTP/1.1
Host:127.0.0.1:8000
User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:1.9.0.1)Gecko/2008070208Firefox/3.0.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-cn,zh;q=0.5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive:300
Connection:keep-alive
Referer:http://127.0.0.1:8000/?username=111&password=222
Content-Type:application/x-www-form-urlencoded
Content-Length:25
username=111&password=222

GET的运行结果演示:

 

GET/?username=111&password=222HTTP/1.1
Host:127.0.0.1:8000
User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:1.9.0.1)Gecko/2008070208Firefox/3.0.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-cn,zh;q=0.5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive:300
Connection:keep-alive
Referer:http://127.0.0.1:8000/?username=1&password=2

POST文件上传的结果演示:

 

POST/?username=111&password=222HTTP/1.1
Host:127.0.0.1:8000
User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:1.9.0.1)Gecko/2008070208Firefox/3.0.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-cn,zh;q=0.5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive:300
Connection:keep-alive
Referer:http://127.0.0.1:8000/?username=111&password=222
Content-Type:multipart/form-data;boundary=---------------------------23757983230932
Content-Length:1704
-----------------------------23757983230932
Content-Disposition:form-data;name="phototitle"
12
-----------------------------23757983230932
Content-Disposition:form-data;name="photo";filename="技术考核题.txt"
Content-Type:text/plain
技术考核
本次是个编程题,题目选Java/语言进行回答。
问题描述:
假设你的爱好是集邮。目前总共有N种不同的邮票,编号为从0到N-1.每种邮票的价钱被定义在数组int[]prices中(序号从0开始,数组的第i个元素表示第i种邮票的价格)。
你的目标是收集尽可能多种的邮票。你当前拥有的邮票存储在int[]have这个数组中。初始时,你没有钱,但是你可以卖掉已有邮票来买不同的邮票。返回你能收集到的不同种邮票的最大数量。
定义:
class:PostmarksCollection
method:numberOfDistinctPostmarks
Parameters:int[],int[]
Returns:int
Methodsignature:publicintnumberOfDistinctPostmarks(int[]prices,int[]have)
//为了进行测试,必须保证是public
约束:
1)N从1到50
2)prices中的元素数量刚好是N个元素
3)prices中的元素的值,从1到1,000,000
4)have中的元素数量是0个到N个
5)have中的每个元素是不同的
6)have中的每个元素的值是从0到N-1.
例如:
1)
{13,10,14,20}
{3,0,2,1}
Returns:4
你已经拥有所有种类的邮票。
2)
{7,5,9,7}
{}
Returns:0
你开始没有任何邮票,所以你也不能组任何事情。
3)
{4,13,9,1,5}
{1,3,2}
Returns:4
卖掉邮票2,买入邮票0和4,(邮票2的价钱是9,邮票0的价钱是4,邮票4的价钱是5,卖掉2刚好买入0和4)
4)
{16,32,13,2,17,10,8,8,20,17}
{7,0,4,1,6,8}
Returns:8
--------------------------------------------------------------------------------
使用Java请在此处答题(请使用JDK5.0编译,编译不能通过者不计算分数)
-----------------------------23757983230932--

 

file_get_contents超时的问题

请有使用file_get_contents的同学在调用前进行设置
ini_set('default_socket_timeout', $seconds);
当PHP读取php.ini配置文件中的所有设置信息的同时,它提供了采用ini_set()函数根据per-scrīpt原则更改这些设置的功能。此函数接收两个参数:需要调整的配置变量名,以及变量的新值。

例如,在某脚本出现时增加最大执行时间(maximum execution time):

<?php

ini_set('max_execution_time', 600)
ini_set('display_errors','1');//php默认是不显示错误的,这样可以把错误设置打开
// more code

?>;

这样的设置将仅仅影响被设置的脚本。一旦脚本执行完毕,该变量将自动恢复到原始值。

<?php
$ctx = stream_context_create(array(
    'http' => array(
        'timeout' => 1
        )
    )
);
file_get_contents("http://example.com/", 0, $ctx);
?>

< ?php
$file_contents = file_get_contents('http://www.ccvita.com/');
echo $file_contents;
?>

换成curl函数的使用示例:

< ?php
$ch = curl_init();
$timeout = 5;
curl_setopt ($ch, CURLOPT_URL, 'http://www.ccvita.com');
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$file_contents = curl_exec($ch);
curl_close($ch);

echo $file_contents;
?>

file_get_contents来post数据:

HTTP POST with file_get_contents  
$post_variables = array('usernamed' => 'rasmus');

$content = http_build_query($post_variables);

$content_length = strlen($content);

$options = array(

    'http'=>array(

        'method'  => 'POST',

        'header'  =>

              "Content-type: application/x-www-form-urlencoded\r\n" .  

              "Content-length: $content_length\r\n",

        'content' => $content
    )

);
$context = stream_context_create($options);

$index = file_get_contents('http://www.example.com/index.php', false, $context);
 

Zend Guard与Zend Optimizer的关系及兼容性

Zend Guard加密后的PHP源程序需要环境中安装Zend Optimizer才可以运行,

同时Zend Optimizer在加密的过程中也可以实现优化代码的作用。

以下为各个Zend Guard版本与Zend Optimizer各版本的对应关系:

Zend Encoder / SafeGuard 3.1 (HOST ID) - Optimizer 2.5.x
Zend Encoder / SafeGuard 3.6 (Zend ID) - Optimizer 2.5.2
Zend Guard 4.x (Basic Encoding) - Optimizer 2.6.x
Zend Guard 5.0 (PHP 4, Basic Encoding) - Optimizer 2.6.x
Zend Guard 4.x (Full Obfuscation) - Optimizer 3.0.x
Zend Guard 5.0 (PHP 4, Full Obfuscation) - Optimizer 3.0.x
Zend Guard 5.0 (PHP 5, All Encoding) - Optimizer 3.3.x

php 二维数组排序

用到二维数组排序,到手册里面查了下,有这样一个很不错的函数,和数据库里面的order by功能是一样的,把二位数组当成一个数据库的表。数组的key就相当于标的列,数组的value相当于标的行:
$XML_deed_temp=array(
array(’deed_id’=>1,’total’=>’b101′),
array(’deed_id’=>2,’total’=>’3′),
array(’deed_id’=>2,’total’=>’4′),
array(’deed_id’=>5,’total’=>’a5′),
array(’deed_id’=>8,’total’=>’a8′),
array(’deed_id’=>12,’total’=>’a12′),
array(’deed_id’=>11,’total’=>’a11′),
array(’deed_id’=>6,’total’=>’a6′)
);

上面的数组可以看成如下一个数据库表:
deed_id total
—————————-
1 b101
2 3
2 4
5 a5
8 a8
12 a12
11 a11
6 a6
——————————-
排序的时候先要取出其中的一列,然后就可以这样:
array_multisort($sortdeed,, SORT_ASC, $XML_deed_temp);
$XML_deed_temp就是要排序的数组,$sortdeed,就是要排序的列的数组(这个数组要先foreach $XML_deed_temp然后将deed_id那一列取出放到$sortdeed数组里面),如果要实现order by col1,col2这样的,可以把多个列取出进行排序,排序先按col1排,再按col2排

$XML_deed_temp=array(
array('deed_id'=>1,'total'=>'b101'),
array('deed_id'=>2,'total'=>'3'),
array('deed_id'=>2,'total'=>'4'),
array('deed_id'=>5,'total'=>'a5'),
array('deed_id'=>8,'total'=>'a8'),
array('deed_id'=>12,'total'=>'a12'),
array('deed_id'=>11,'total'=>'a11'),
array('deed_id'=>6,'total'=>'a6')
);
foreach($XML_deed_temp as $t_k=>$t_v){
$deed_id[]=$t_v['deed_id'];
$total[]=$t_v['total'];
//print_r($t_v);
}
array_multisort($deed_id, SORT_ASC, $total, SORT_ASC, $XML_deed_temp);
print_r($XML_deed_temp);
 

PHP5中的this self parent关键字

PHP5是一具备了大部分面向对象语言的特性的语言,比PHP4有了很多的面向对象的特性,但是有部分概念也比较绕人,所以今天拿出来说说,说的不好,请高手见谅. (阅读本文,需要了解PHP5的面向对象的知识)

首先我们来明白上面三个关键字: this,self,parent,从字面上比较好理解,是指这,自己,父亲,呵呵,比较好玩了,我们先建立几个概念,这三个关键字分别是用在什么地方呢?我们初步解释一下,this是指向当前对象的指针(我们姑且用C里面的指针来看吧),self是指向当前类的指针,parent是指向父类的指针。

[separator]

(1) this

1 <?php
2
3 class UserName
4 {
5 //定义属性
6 private $name;
7
8 //定义构造函数
9 function __construct( $name )
10 {
11 $this->name = $name; //这里已经使用了this指针
12 }
13
14 //析构函数
15 function __destruct(){}
16
17 //打印用户名成员函数
18 function printName()
19 {
20 print( $this->name ); //又使用了this指针
21 }
22 }
23
24 //实例化对象
25 $nameObject = new UserName( "heiyeluren" );
26
27 //执行打印
28 $nameObject->printName(); //输出: heiyeluren
29
30 //第二次实例化对象
31 $nameObject2 = new UserName( "PHP5" );
32
33 //执行打印
34 $nameObject2->printName(); //输出:PHP5
35 ?>

我们看,上面的类分别在11行和20行使用了this指针,那么当时this是指向谁呢?其实this是在实例化的时候来确定指向谁,比如第一次实例化对象的时候(25行),那么当时this就是指向$nameObject对象,那么执行18行的打印的时候就把print( $this-><name )变成了print( $nameObject->name ),那么当然就输出了"heiyeluren"。第二个实例的时候,print( $this->name )变成了print( $nameObject2->name ),于是就输出了"PHP5"。所以说,this就是指向当前对象实例的指针,不指向任何其他对象或类。

 

(2)self

首先我们要明确一点,self是指向类本身,也就是self是不指向任何已经实例化的对象,一般self使用来指向类中的静态变量。

1 <?php
2
3 class Counter
4 {
5 //定义属性,包括一个静态变量
6 private static $firstCount = 0;
7 private $lastCount;
8
9 //构造函数
10 function __construct()
11 {
12 $this->lastCount = ++selft::$firstCount; //使用self来调用静态变量,使用self调用必须使用::(域运算符号)
13 }
14
15 //打印最次数值
16 function printLastCount()
17 {
18 print( $this->lastCount );
19 }
20 }
21
22 //实例化对象
23 $countObject = new Counter();
24
25 $countObject->printLastCount(); //输出 1
26
27 ?>

我们这里只要注意两个地方,第6行和第12行。我们在第二行定义了一个静态变量$firstCount,并且初始值为0,那么在12行的时候调用了这个值得,使用的是self来调用,并且中间使用"::"来连接,就是我们所谓的域运算符,那么这时候我们调用的就是类自己定义的静态变量$frestCount,我们的静态变量与下面对象的实例无关,它只是跟类有关,那么我调用类本身的的,那么我们就无法使用this来引用,可以使用self来引用,因为self是指向类本身,与任何对象实例无关。换句话说,假如我们的类里面静态的成员,我们也必须使用self来调用。

(3)parent

我们知道parent是指向父类的指针,一般我们使用parent来调用父类的构造函数。

1 <?php
2
3 //基类
4 class Animal
5 {
6 //基类的属性
7 public $name; //名字
8
9 //基类的构造函数
10 public function __construct( $name )
11 {
12 $this->name = $name;
13 }
14 }
15
16 //派生类
17 class Person extends Animal //Person类继承了Animal类
18 {
19 public $personSex; //性别
20 public $personAge; //年龄
21
22 //继承类的构造函数
23 function __construct( $personSex, $personAge )
24 {
25 parent::__construct( "heiyeluren" ); //使用parent调用了父类的构造函数
26 $this->personSex = $personSex;
27 $this->personAge = $personAge;
28 }
29
30 function printPerson()
31 {
32 print( $this->name. " is " .$this->personSex. ",this year " .$this->personAge );
33 }
34 }
35
36 //实例化Person对象
37 $personObject = new Person( "male", "21");
38
39 //执行打印
40 $personObject->printPerson(); //输出:heiyeluren is male,this year 21
41
42 ?>

我们注意这么几个细节:成员属性都是public的,特别是父类的,是为了供继承类通过this来访问。我们注意关键的地方,第25行:parent::__construct( "heiyeluren" ),这时候我们就使用parent来调用父类的构造函数进行对父类的初始化,因为父类的成员都是public的,于是我们就能够在继承类中直接使用this来调用。

总结:

this是指向对象实例的一个指针,self是对类本身的一个引用,parent是对父类的引用。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/heiyeshuwu/archive/2004/11/03/165828.aspx

PHP中的public、protected与private修饰符

public:方法或者属性在任何作用域都可以访问到,而且这是默认的,如果没有为一个属性或方法指定访问修饰符,它将是public。

protected:方法或者属性只能从类或者继承类的一个成员中访问到。

private:方法或者属性只能从类的一个成员中访问到,而且无法从继承类的成员中访问到。经过private便签标记的方法或者属性可以在继承类中重新定义。每一个类只能看到它自己定义的私有方法。

[separator]

 

        

  1. <?php
  2.     

  3. class MyClass{
  4.     

  5. public $public = 'Public';
  6.     

  7. protected $protected = 'Protected';
  8.     

  9. private $private = 'Private';
  10.     

  11. function printHello()
  12.     

  13. {
  14.     

  15. echo $this->public;
  16.     

  17. echo $this->protected;
  18.     

  19. echo $this->private;
  20.     

  21. }
  22.     

  23. }
  24.     

  25. $obj = new MyClass();
  26.     

  27. echo $obj->public; // Works
  28.     

  29. echo $obj->protected; // Fatal Error
  30.     

  31. echo $obj->private; // Fatal Error //私有和受保护的属性都不能直接引用
  32.     

  33. $obj->printHello(); // Shows Public, Protected and Private
  34.     

  35. /**
  36.     

  37. * Define MyClass2
  38.     

  39. */
  40.     

  41. class MyClass2 extends MyClass{
  42.     

  43. // We can redeclare the public and protected method, but not private
  44.     

  45. protected $protected = 'Protected2';
  46.     

  47. function printHello()
  48.     

  49. {
  50.     

  51. echo $this->public;
  52.     

  53. echo $this->protected;
  54.     

  55. echo $this->private;
  56.     

  57. }
  58.     

  59. }
  60.     

  61. $obj2 = new MyClass2();
  62.     

  63. echo $obj->public; // Works
  64.     

  65. echo $obj2->private; // Undefined //私有属性可以重新定义,但MyClass2里面没有定义
  66.     

  67. echo $obj2->protected; // Fatal Error //受保护的属性不能重新定义
  68.     

  69. $obj2->printHello(); // Shows Public, Protected2, not Private
  70.     

  71. ?>

PHP abstract final static 关键字

在开始看这篇文章前 请首先读以下文章:

http://127.0.0.1/wordpress/read.php?146

http://127.0.0.1/wordpress/read.php?147

 
从PHP 5 开始 类的定义又增加了 abstract、final和static 关键字
1.abstract 关键字
 
面向对象程序通过类的分层结构构建起来.在单重继承语言如PHP中,类的继承是树状的.
一个根类有一个或更多的子类,再从每个子类继承出一个或更多下一级子类.
当然,可能存在多个根类,用来实现不同的功能.
用abstract定义的类不能被实例化。有一个函数为abstract的类,这个类就必须是abstract,子类必须
定义所有的父类中的abstract函数,子类中函数的作用域只能被扩大,不能缩小。
在一个良好设计的体系中,每个根类都应该有一个有用的接口,可以被应用代码所使用.而抽象类就可以提供多个实用的接口.
如果你建立了一个只有抽象方法的类,那么你就定义了一个接口(interface).

在抽象类中定义的方法,也都是抽象方法,

当然,抽象方法与普通的方法不一样,它只是子类中普通方法的一个占位符(只是占个地主不启作用),没有任何代码,也没有"{}"包含,而是以";"结束的.
 

abstract class aaa{
abstract function bbb(); // 这里没有代码的部分
}
 

当然,如果一个类中有一个或多个抽象的方法,那么这个类就成了抽象类.抽象类不能实例化,只能继承,
然后,实例化子类.值得注意的是,它的子类必须重复写所有方法(all method),这样,子类就成为普通的类,才可以实例化.
否则,子类中只要有一个抽象方法,那么子类必须声明是抽象类,在class关键字前加上abstract.
抽象的类的声明方法:
(1).使用abstact限定语.
//定义抽象类aaa为母类
abstract class aaa{
abstract function bbb();
abstract function ccc();
}
//用 extends 关键字 定义普通子类 childfromaaa
//继承aaa抽象类
class childfromaaa extends aaa{
//重写所有抽象类中的方法
public function bbb(){
//.....
}
public function ccc(){
//...
}
}
//实例化子类
$child=new childfromaaa;//right

[separator]

 
另外的演示代码:
<?php
abstract class AbstractClass
{
// Force Extending class to define this method
abstract protected function getValue();
abstract protected function
prefixValue($prefix);

// Common method
public function printOut() {
print
$this->getValue() . "\n";
}
}

class ConcreteClass1 extends AbstractClass
{
protected function
getValue() {
return
"ConcreteClass1";
}

public function prefixValue($prefix) {
return
"{$prefix}ConcreteClass1";
}
}

class ConcreteClass2 extends AbstractClass
{
public function
getValue() {
return
"ConcreteClass2";
}

public function prefixValue($prefix) {
return
"{$prefix}ConcreteClass2";
}
}

$class1 = new ConcreteClass1;
$class1->printOut();
echo
$class1->prefixValue('FOO_') ."\n";

$class2 = new ConcreteClass2;
$class2->printOut();
echo
$class2->prefixValue('FOO_') ."\n";
?>

The above example will output:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2






FOO_ConcreteClass2
(2).PHP中有interface和implements关键字.你可以用interface来代替抽象类,用implements来代替extends来说明你的类定义或使用一个接口.
//定义抽象基类
interface Foo{
function a(Foo $foo);
}
//定义另一个抽象类
interface Bar{
function b(Bar $bar);
}
//定义子类childfromaaa
//继承aaa抽象类(接口)
//实现多类继承
class FooBar implements Foo,Bar{
functiona(Foo$foo){
//...
}
functionb(Bar$bar){
//...
}
}

$a=newFooBar;
$b=newFooBar;

$a->a($b);
$a->b($b);

2.final

final/final关键字
PHP5中新增加了final关键字,它可以加在类或类方法前。标识为final的类方法,在子类中不能被覆写。标识为final的类,不能被继承,而且其中的方法都默认为final类型。
Final方法:
<?php
classFoo{
final function bar(){
//…
}
}
?>
Final类:
<?php
final class Foo{
//classdefinition
}
//下面这一行是错误的
//classBork extends Foo{}
?>

3.static

 
当static 关键字应用在变量上..
 
静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失。看看下面的例子:
 
<?PHP
function Test()
{
static $w3sky = 0;
echo $w3sky;
$w3sky++;
}
?>
每次执行函数 $w3sky都会自动增加1
 
当static关键字应用在类的属性 和方法上..
 

static关键字在类中是,描述一个成员是静态的,static能够限制外部的访问,因为static后的成员是属于类的,是不属于任何对象实例,其他类是无法访问的,只对类的实例共享,能一定程序对该成员尽心保护。类的静态变量,非常类似全局变量,能够被所有类的实例共享,类的静态方法也是一样的,类似于全局函数。类的静态方法能访问类的静态的属性。另外说明的是,static的成员,必须使用self来访问,使用this会出错。

 

1:class classname
{
private static $test1; // 用来定义静态属性 并用private 保护其不备集成类或实例干扰

public $test2;
public static function Initialization()
{
return self::$test1;
}

public function test (){

return self::$test1;

}
}

$test = New classname();

$test->test(); //调用公共方法

$test->test2;

以下是不允许的

$test->Initialization();

$test->test1;

 

php数组合并

php的数组在这门语言里使用得非常多。数组的一些常见操作像split/explode,join/implode,排序(sort,asort,ksort,arsort),两数组合并(array_combine),键值翻转(array_flip),当然还有比较复杂的数组合并。
数组合并至少有4种形式。
1.第一种php数组合并方式(使用[]合并)

$a = array(1=>'a',2=>'b',3=>'c');
$b = array(1=>'d',2=>'e',3=>'f');

foreach($b as $v)
{
$a[] = $v;
}
var_export($a);
得到

[separator]

array (
1 => 'a',
2 => 'b',
3 => 'c',
4 => 'd',
5 => 'e',
6 => 'f',
)
这种方式的数组合并,新增元素的键值是在原来数字键值之上增加。
如果原来的键值不是数字的,那么新增元素的键值将从0开始。

2.第二种数组合并方式(使用array_unshift合并)

$a = array(1=>'a',2=>'b',3=>'c');
$b = array(1=>'d',2=>'e',3=>'f');

foreach($b as $v)
{
array_unshift($a,$v);
}
var_export($a);
得到

array (
0 => 'f',
1 => 'e',
2 => 'd',
3 => 'a',
4 => 'b',
5 => 'c',
)
可以看到,使用array_unshift方式添加元素,每次都会在数组头部新增元素,并且这些元素的键值总是从0开始,整个数组的键将重新从0开始计算。
3.使用array_merge合并php数组

$a = array(1=>'a',2=>'b',3=>'c');
$b = array(1=>'d',2=>'e',3=>'f');
$a = array_merge($a,$b);
var_export($a);
运算结果是

array (
0 => 'a',
1 => 'b',
2 => 'c',
3 => 'd',
4 => 'e',
5 => 'f',
)
可以看到数组的键也被从0开始重新计算了。

4.使用+合并php数组

$a = array(1=>'a',2=>'b',3=>'c');
$b = array(1=>'d',2=>'e',3=>'f');
$a = $a+$b; // $a += $b;
var_export($a);
我们得到了令人惊讶的结果

array (
1 => 'a',
2 => 'b',
3 => 'c',
)
数组$b被忽略了。我们可以看到,如果数组$b中有和$a重复键值的元素,那么这些元素将被忽略。换言之:保留键值,如果有重复,以第一个数组中的键为准。

© 2018 技术控 All Rights Reserved