本文目录一览:
- 1、php魔术方法。。
- 2、怎么样在php配置中加载魔术常量
- 3、PHP魔术变量是什么求详解,不要去复制然后来粘贴
- 4、请详细说明一下php5中的魔术方法
- 5、PHP中魔术变量__METHOD__与__FUNCTION__的区别
php魔术方法。。
在 PHP 里,将所有以 __(两个下划线)开头的类方法保留为魔术方法,所以在定义类方法时,除了上述魔术方法,建议不要以 __ 为前缀。
魔术方法的引入是对面向对象编程思想的进一步实现,重载就是通过魔术方法来实现的。
PHP 魔术方法主要有:
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(),__sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等。
最常见的是__construct(), __destruct(),__get(), __set()等:
__construct和__destruct是类的构造函数和析构函数。
怎么样在php配置中加载魔术常量
PHP中,有不少很好用的魔术变量,用好之,能事半功倍,下面小结之:
1 _LINE_
显示当前代码的行数:
echo "This is line number : ". __LINE__;
2 _FILE_
显示当前文件的路径
3 _METHOD_
显示当前方法的名,比如
class Magicconstant
{
function __construct()
{
echo "This is function a";
}
function b()
{
echo "br/";
echo "This is function b";
echo "br/";
echo __METHOD__;
}
}
$cm = new Magicconstant();
$cm-b();
显示
This is function a
This is function b
Magicconstant::b
4 _FUNCTION_
显示当前所在函数的名
function b()
{
echo "br/";
echo "This is function b";
echo "br/";
echo __FUNCTION__;
}
输出:
This is function b
Magicconstant::b
5 _DIR_
显示当前目录名,如
echo "The directory name is : ". __DIR__;
输出:
The directory name is : D:\wamp\www
6 _CLASS_
显示当前的类
class Magicconstant
{
function __construct()
{
echo "The class name is : ".__CLASS__;
}
}
$cm = new Magicconstant();
显示:
The class name is : Magicconstant
7 _NAMESPACE_
显示当前命名空间
namespace MagicConstant
{
echo "The namespace is : ".__NAMESPACE__;
}
输出:
The namespace is : MagicConstant
8 _sleep_
_sleep_用在将类序列化之前,
?php
class User
{
public $userName = '';
public $userAddress = '';
public $userPhone = '';
public function setName($name='')
{
$this-userName = $name;
}
function setAddress($address='')
{
$this-userAddress = $address;
}
function setPhone($phone='')
{
$this-userPhone = $phone;
}
function __sleep()
{
return array('userAddress','userPhone');
// This will serialize only address and Phone number but not Name
}
}
?
?php
$User = new User();
$User-setName('Avinash');
$User-setAddress('Address Here');
$User-setPhone('1234567890');
$serialData = serialize($User);
echo $serialData;
?
OutPut: O:4:"User":2:{s:11:"userAddress";s:12:"Address Here";s:9:"userPhone";s:10:"1234567890";}
程序运行时, serialize() 检查类中是否有 __sleep() ,如果有,则该函数将在任何序列化之前运行. 该函数必须返回一个需要进行序列化保存的成员属性数组,并且只序列化该函数返回的这些成员属性. 该函数有两个作用: 第一. 在序列化之前,关闭对象可能具有的任何数据库连接等. 第二. 指定对象中需要被序列化的成员属性,如果某个属性比较大而不需要储存下来,可以不把它写进__sleep()要返回的数组中,这样该属性就不会被序列化
又如:
class Test {
public $mySecret; //我的秘密不想让人知道
public function __construct($secret) {
$this-mySecret = $secret;
}
public function __sleep() {
$this-mySecret = "你休想知道我的秘密!";
return array('mySecret'); //一定要返回变量,不然返回的是个空,所以序列化也就没有东西了。
}
}
$test = new Test("我的心里话 我爱某某某");
echo serialize($test); //输出 O:4:"Test":1:{s:8:"mySecret";s:28:"你休想知道我的秘密!";}
_wakeup_
用在反序列化时:
?php
class User
{
public $userName = '';
public $userAddress = '';
public $userPhone = '';
public function setName($name='')
{
$this-userName = $name;
}
function setAddress($address='')
{
$this-userAddress = $address;
}
function setPhone($phone='')
{
$this-userPhone = $phone;
}
function __sleep()
{
return array('userAddress','userPhone');
// This will serialize only address and Phone number but not Name
}
function __wakeup()
{
echo "In Wakeup function"."br/";
}
}
?
?php
$User = new User();
$User-setName('Avinash');
$User-setAddress('Address Here');
$User-setPhone('1234567890');
$serialData = serialize($User);
echo $serialData;
echo "br/";
var_dump(unserialize($serialData));
?
Output:
In Wakeup function
object(User)#2 (3) {
["userName"]=
string(0) ""
["userAddress"]=
string(12) "Address Here"
["userPhone"]=
string(10) "1234567890"
}
//以上信息转自 不代表个人观点 仅供参考 若满意 请采纳本答案
PHP魔术变量是什么求详解,不要去复制然后来粘贴
魔术变量就是指那些根据不同环境有不同的取值
比如
__FILE__
就是一个典型的魔术变量,当它出现在a.php文件里时它的值就是a.php的具体路径,出现在b.php文件里就是b.php的具体路径
其他的一些魔术变量还有__FUNCTION__, __CLASS__
总之这些变量的值往往不是固定的,变来变去的,很神奇,像魔术一样,故叫做魔术变量
请详细说明一下php5中的魔术方法
PHP处理对象部分的内核完全重新开发过,提供更多功能的同时也提高了性能。在以前版本的php中,处理对象和处理基本类型(数字,字符串)的方式是一样的。这种方式的缺陷是:当将对象赋值给一个变量时,或者通过参数传递对象时,对象将被完全拷贝一份。在新的版本里,上述操作将传递引用(可以把引用理解成对象的标识符),而非值。
很多PHP程序员可能甚至没有察觉到老的对象处理方式。事实上,大多数的php应用都可以很好地运行。或者仅仅需要很少的改动。
私有和受保护成员
PHP5引入了私有和受保护成员变量的概念。我们可以用它来定义类成员的可见性。
例子
受保护成员可以被子类访问, 而私有成员只能被类本身访问。
代码:--------------------------------------------------------------------------------
?php
class MyClass {
private $Hello = "Hello, World!\n";
protected $Bar = "Hello, Foo!\n";
protected $Foo = "Hello, Bar!\n";
function printHello() {
print "MyClass::printHello() " . $this-Hello;
print "MyClass::printHello() " . $this-Bar;
print "MyClass::printHello() " . $this-Foo;
}
}
class MyClass2 extends MyClass {
protected $Foo;
function printHello() {
MyClass::printHello(); /* Should print */
print "MyClass2::printHello() " . $this-Hello; /* Shouldn't print out anything */
print "MyClass2::printHello() " . $this-Bar; /* Shouldn't print (not declared)*/
print "MyClass2::printHello() " . $this-Foo; /* Should print */
}
}
$obj = new MyClass();
print $obj-Hello; /* Shouldn't print out anything */
print $obj-Bar; /* Shouldn't print out anything */
print $obj-Foo; /* Shouldn't print out anything */
$obj-printHello(); /* Should print */
$obj = new MyClass2();
print $obj-Hello; /* Shouldn't print out anything */
print $obj-Bar; /* Shouldn't print out anything */
print $obj-Foo; /* Shouldn't print out anything */
$obj-printHello();
?
--------------------------------------------------------------------------------
私有方法和受保护方法
PHP5也引入了私有方法和受保护方法的概念。
例子:
代码:--------------------------------------------------------------------------------
?php
class Foo {
private function aPrivateMethod() {
echo "Foo::aPrivateMethod() called.\n";
}
protected function aProtectedMethod() {
echo "Foo::aProtectedMethod() called.\n";
$this-aPrivateMethod();
}
}
class Bar extends Foo {
public function aPublicMethod() {
echo "Bar::aPublicMethod() called.\n";
$this-aProtectedMethod();
}
}
$o = new Bar;
$o-aPublicMethod();
?
--------------------------------------------------------------------------------
以前的不使用类的老代码,没有访问修饰符(public, protected, private)的代码可以不经改动运行。
抽象类和抽象方法
Php5也引入了抽象类和抽象方法的概念。抽象方法只是声明了方法的签名并不提供它的实现。包含抽象方法的类必须被声明成抽象类。
例子:
代码:--------------------------------------------------------------------------------
?php
abstract class AbstractClass {
abstract public function test();
}
class ImplementedClass extends AbstractClass {
public function test() {
echo "ImplementedClass::test() called.\n";
}
}
$o = new ImplementedClass;
$o-test();
?
--------------------------------------------------------------------------------
抽象类不能被实例化。以前的不使用抽象类的老代码可以不经改动运行。
接口
Php5引入了接口。一个类可以实现多个接口。
例子:
代码:--------------------------------------------------------------------------------
?php
interface Throwable {
public function getMessage();
}
class MyException implements Throwable {
public function getMessage() {
// ...
}
}
?
--------------------------------------------------------------------------------
以前的不使用接口的老代码可以不经改动运行
类的型别提示
PHP5依然是弱类型的,不过在定义函数参数时,可以使用类的型别提示来声明期望传入的对象类型
Example
代码:--------------------------------------------------------------------------------
?php
interface Foo {
function a(Foo $foo);
}
interface Bar {
function b(Bar $bar);
}
class FooBar implements Foo, Bar {
function a(Foo $foo) {
// ...
}
function b(Bar $bar) {
// ...
}
}
$a = new FooBar;
$b = new FooBar;
$a-a($b);
$a-b($b);
?
--------------------------------------------------------------------------------
和其他强类型语言一样,php5类的型别提示在运行期间检查而非编译期间检查。即:
代码:--------------------------------------------------------------------------------
?php
function foo(ClassName $object) {
// ...
}
?
和下面的代码是一样的:
?php
function foo($object) {
if (!($object instanceof ClassName)) {
die("Argument 1 must be an instance of ClassName");
}
}
?
--------------------------------------------------------------------------------
这个语法只适用于类,不适用于内建类型。
Final
PHP 5 引入了final关键字来声明final成员和final方法。final成员和final方法不能被子类覆盖。
Example
代码:--------------------------------------------------------------------------------
?php
class Foo {
final function bar() {
// ...
}
}
?
--------------------------------------------------------------------------------
更进一步,可以把类声明成final。将类声明成final可以阻止这个类被继承。final类里面的方法缺省地都是final的,无需再声明一次。
Example
代码:--------------------------------------------------------------------------------
?php
final class Foo {
// class definition
}
// the next line is impossible
// class Bork extends Foo {}
?
--------------------------------------------------------------------------------
属性不能定义成为final.
以前的不使用final的老代码可以不经改动运行.
对象克隆
Php4没有提供一种机制来让用户自己定义复制构造子(copy constructor)控制对象的复制过程。Php4做二进制的拷贝,因而很精确地复制了对象的所有属性。
精确地复制对象的所有属性可能并不是我们一直想要的。有个例子可以很好地说明我们确实需要复制构造子:比如一个GTK Window的对象 a。 a持有它所需要的全部资源。当复制的这个GTK Window到对象b时候,我们更希望b持有新的资源对象。再举个例子:对象a包含了一个对象c, 当你把对象a 复制到对象c的时候。我们可能更希望对象b包含一个新的对象c的copy, 而不是一个对象c的引用。(译者注:这里所说的就是浅克隆和深克隆。)
对象的复制是通过clone这个关键字达到的(Clone调用被克隆对象的__clone()方法)。对象的__clone方法不能够直接被调用。
代码:--------------------------------------------------------------------------------
?php
$copy_of_object = clone $object;
?
--------------------------------------------------------------------------------
当developer创建对象的一份拷贝的时候,php5将会检查 __clone()方法是否存在。如果不存在,那么它就会呼叫缺省的__clone()方法,复制对象的所有属性。如果__clone()方法已经定义过,那么_clone()方法就会负责设置新对象的属性。为了方便起见,Engine会缺省地复制所有的属性。所以在__clone()方法中,只需要覆盖那些需要更改的属性就可以了。如下:
Example
代码:--------------------------------------------------------------------------------
?php
class MyCloneable {
static $id = 0;
function MyCloneable() {
$this-id = self::$id++;
}
function __clone() {
$this-address = "New York";
$this-id = self::$id++;
}
}
$obj = new MyCloneable();
$obj-name = "Hello";
$obj-address = "Tel-Aviv";
print $obj-id . "\n";
$obj_cloned = clone $obj;
print $obj_cloned-id . "\n";
print $obj_cloned-name . "\n";
print $obj_cloned-address . "\n";
?
--------------------------------------------------------------------------------
统一构造函数
Php5允许开发者声明一个类的构造方法。拥有构造方法的类在每次创建新的对象的时候都会呼叫这个方法,因此构造方法适合对象在被使用之前的初始化工作
Php4中,构造方法的名称和类的名称一样。考虑到从子类构造方法呼叫父类构造方法的情况是非常普遍的,而将类从一个继承体系中搬迁引起的父类变更就常常导致需要更改类的构造方法,php4的做法显然是不太合理的。
Php5引入了一个声明构建函数的标准方法: __construct().如下:
Example
代码:--------------------------------------------------------------------------------
?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
$obj = new BaseClass();
$obj = new SubClass();
?
--------------------------------------------------------------------------------
为保持向后的兼容性,如果php5不能够找到 __construct(),它会寻找老式的构造方法,即与类同名的方法。简单的说,只有当老代码里包含了一个__construct()方法的时候,才存在一个兼容性的问题。
析构方法
对于面向对象的编程来说,可以定义析构方法是非常有用的一个功能。析构方法可以用来记录调试信息,关闭数据库连接等等一些清除收尾的工作。Php4中没有析构方法,尽管php4已经支持可以注册一个函数以便请求结束的时候被调用。
Php5引进的析构方法的概念和其他面向对象的语言(比如java)是一致的。当指向这个对象的最后一个引用被销毁的时候,析构方法被调用,调用完成后释放内存。注意:析构方法不接受任何参数。
Example
代码:--------------------------------------------------------------------------------
?php
class MyDestructableClass {
function __construct() {
print "In constructor\n";
$this-name = "MyDestructableClass";
}
function __destruct() {
print "Destroying " . $this-name . "\n";
}
}
$obj = new MyDestructableClass();
?
--------------------------------------------------------------------------------
和构建方法一样,父类的析构方法也不会被隐含调用。子类可以在自己的析构方法通过调用parent::__destruct()来显式地调用它。
Constants
Php5引入了class级别的常量。
代码:--------------------------------------------------------------------------------
?php
class Foo {
const constant = "constant";
}
echo "Foo::constant = " . Foo::constant . "\n";
?
--------------------------------------------------------------------------------
老的没有使用const的代码仍然正常运行。
Exceptions
Php4没有异常控制。Php5引入了和其它语言(java)相似的异常控制模式。应该注意的是php5里面支持捕捉全部异常,但是不支持finally子句。
在catch语句块里面,可以重新抛出异常。也可以有多个catch语句,在这种情况下,被捕捉到的异常从上往下依次比较和catch语句比较异常,第一个类型匹配的catch语句将会被执行。如果一直搜索到底还没有发现匹配的catch子句,则寻找下一个try/catch语句。最后不能捕捉的异常将被显示出来。如果异常被捕捉,那么程序会接着catch语句块的下面开始执行。
Example
代码:--------------------------------------------------------------------------------
?php
class MyException {
function __construct($exception) {
$this-exception = $exception;
}
function Display() {
print "MyException: $this-exception\n";
}
}
class MyExceptionFoo extends MyException {
function __construct($exception) {
$this-exception = $exception;
}
function Display() {
print "MyException: $this-exception\n";
}
}
try {
throw new MyExceptionFoo('Hello');
}
catch (MyException $exception) {
$exception-Display();
}
catch (Exception $exception) {
echo $exception;
}
?
--------------------------------------------------------------------------------
上面的例子表明可以定义一个并不继承自 Exception的异常类,但是,最好还是从Exception继承并定义自己的异常。这是因为系统内建的Exception类能够收集到很多有用的信息, 而不继承它的异常类是得不到这些信息的。下面的php代码模仿了系统内建Exception类。每个属性后面都加了注释。每个属性都有一个getter,由于这些getter方法经常被系统内部处理调用,所以这些方法被标明了final。
Example
代码:--------------------------------------------------------------------------------
?php
class Exception {
function __construct(string $message=NULL, int code=0) {
if (func_num_args()) {
$this-message = $message;
}
$this-code = $code;
$this-file = __FILE__; // of throw clause
$this-line = __LINE__; // of throw clause
$this-trace = debug_backtrace();
$this-string = StringFormat($this);
}
protected $message = 'Unknown exception'; // exception message
protected $code = 0; // user defined exception code
protected $file; // source filename of exception
protected $line; // source line of exception
private $trace; // backtrace of exception
private $string; // internal only!!
final function getMessage() {
return $this-message;
}
final function getCode() {
return $this-code;
}
final function getFile() {
return $this-file;
}
final function getTrace() {
return $this-trace;
}
final function getTraceAsString() {
return self::TraceFormat($this);
}
function _toString() {
return $this-string;
}
static private function StringFormat(Exception $exception) {
// ... a function not available in PHP scripts
// that returns all relevant information as a string
}
static private function TraceFormat(Exception $exception) {
// ... a function not available in PHP scripts
// that returns the backtrace as a string
}
}
?
--------------------------------------------------------------------------------
如果我们定义的一异常类都是继承自Exception基类
无兼容性问题。老的代码不会受到这一特性的影响。
Dereferencing objects returned from functions
Php4中不能再次引用函数返回的对象以进一步呼叫返回对象的方法,而php5是可以的。
代码:--------------------------------------------------------------------------------
?php
class Circle {
function draw() {
print "Circle\n";
}
}
class Square {
function draw() {
print "Square\n";
}
}
function ShapeFactoryMethod($shape) {
switch ($shape) {
case "Circle":
return new Circle();
case "Square":
return new Square();
}
}
ShapeFactoryMethod("Circle")-draw();
ShapeFactoryMethod("Square")-draw();
?
--------------------------------------------------------------------------------
静态成员变量能够被初始化。
Example
代码:--------------------------------------------------------------------------------
?php
class foo {
static $my_static = 5;
public $my_prop = 'bla';
}
print foo::$my_static;
$obj = new foo;
print $obj-my_prop;
?
--------------------------------------------------------------------------------
静态方法
PHP 5 引入了静态方法,可以在不实例化类的情况下呼叫静态方法。
Example
代码:--------------------------------------------------------------------------------
?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
?
--------------------------------------------------------------------------------
伪变量$this不能够在静态方法方法中使用。
instanceof
Php5引入了instanceof关键字,允许用它来测试一个对象是一个类的实例,或者是一个派生类的实例,或者实现了某个接口
Example
代码:--------------------------------------------------------------------------------
?php
class baseClass { }
$a = new baseClass;
if ($a instanceof baseClass) {
echo "Hello World";
}
?
--------------------------------------------------------------------------------
Static function variables
现在,静态变量在编译阶段处理。因此程序员可以通过引用为静态变量赋值。这可以改善性能,不过,不能够使用对静态变量的间接引用了。
按引用传递的函数参数现在也可以设置缺省值了。
Example
代码:--------------------------------------------------------------------------------
?php
function my_function($var = null) {
if ($var === null) {
die("$var needs to have a value");
}
}
?
--------------------------------------------------------------------------------
__autoload()
__autoload() 拦截函数在一个未声明的类被初始化的时候自动调用。该类的名字会被自动传递给__autoload()函数。而__autoload()也只有这么唯一的一个参数。
Example
代码:--------------------------------------------------------------------------------
?php
function __autoload($className) {
include_once $className . ".php";
}
$object = new ClassName;
?
--------------------------------------------------------------------------------
可重载的方法呼叫和属性访问
方法呼叫和属性访问都能够通过__call, __get() and __set()方法重载。
Example: __get() and __set()
代码:--------------------------------------------------------------------------------
?php
class Setter {
public $n;
public $x = array("a" = 1, "b" = 2, "c" = 3);
function __get($nm) {
print "Getting [$nm]\n";
if (isset($this-x[$nm])) {
$r = $this-x[$nm];
print "Returning: $r\n";
return $r;
} else {
print "Nothing!\n";
}
}
function __set($nm, $val) {
print "Setting [$nm] to $val\n";
if (isset($this-x[$nm])) {
$this-x[$nm] = $val;
print "OK!\n";
} else {
print "Not OK!\n";
}
}
}
$foo = new Setter();
$foo-n = 1;
$foo-a = 100;
$foo-a++;
$foo-z++;
var_dump($foo);
?
--------------------------------------------------------------------------------
Example: __call()
代码:--------------------------------------------------------------------------------
?php
class Caller {
private $x = array(1, 2, 3);
function __call($m, $a) {
print "Method $m called:\n";
var_dump($a);
return $this-x;
}
}
$foo = new Caller();
$a = $foo-test(1, "2", 3.4, true);
var_dump($a);
?
--------------------------------------------------------------------------------
迭代
当和foreach一起使用对象的时候,迭代的方式被重载过了。缺省的行为是迭代类的所有属性。
Example
代码:--------------------------------------------------------------------------------
?php
class Foo {
public $x = 1;
public $y = 2;
}
$obj = new Foo;
foreach ($obj as $prp_name = $prop_value) {
// using the property
}
?
--------------------------------------------------------------------------------
一个类的所有对象都能够被迭代浏览到, 如果这个类实现了一个空的接口:Traversable. 换句话说,实现了Traversable接口的类可以和foreach一起使用。
接口 IteratorAggregate 和Iterator允许指定类的对象在代码中如何迭代。IteratorAggregate接口有一个方法:getIterator() 必须返回一个数组
Example
代码:--------------------------------------------------------------------------------
?php
class ObjectIterator implements Iterator {
private $obj;
private $num;
function __construct($obj) {
$this-obj = $obj;
}
function rewind() {
$this-num = 0;
}
function valid() {
return $this-num $this-obj-max;
}
function key() {
return $this-num;
}
function current() {
switch($this-num) {
case 0: return "1st";
case 1: return "2nd";
case 2: return "3rd";
default: return $this-num."th";
}
}
function next() {
$this-num++;
}
}
class Object implements IteratorAggregate {
public $max = 3;
function getIterator() {
return new ObjectIterator($this);
}
}
$obj = new Object;
// this foreach ...
foreach($obj as $key = $val) {
echo "$key = $val\n";
}
// matches the following 7 lines with the for directive.
$it = $obj-getIterator();
for($it-rewind(); $it-hasMore(); $it-next) {
$key = $it-current();
$val = $it-key();
echo "$key = $val\n";
}
unset($it);
?
--------------------------------------------------------------------------------
新的__toString方法
可以通过覆盖__toString方法来控制对象到字符串的转换。
Example
代码:---------------------------------------
PHP中魔术变量__METHOD__与__FUNCTION__的区别
本文实例讲述了PHP中魔术变量__METHOD__与__FUNCTION__的区别,分享给大家供大家参考。具体分析如下:
__METHOD__类的方法名(PHP
5.0.0
新加)。返回该方法被定义时的名字(区分大小写)。
__FUNCTION__函数名称(PHP
4.3.0
新加)。自
PHP
5
起本常量返回该函数被定义时的名字(区分大小写)。在
PHP
4
中该值总是小写字母的。
文档解释都是说返回函数(方法)的名字。区别在于:
__FUNCTION__只是返回方法的名字;
__METHOD__返回类的名字和方法的名字。
?php
class
Test{
public
function
doit(){
echo
__FUNCTION__;
}
public
function
doitAgain(){
echo
__METHOD__;
}
}
$obj
=
new
Test();
$obj-doit();
echo
'br';
$obj-doitAgain();
?
输出结果为:
doit
Test::doitAgain
希望本文所述对大家的PHP程序设计有所帮助。