+ -
当前位置:首页 → 问答吧 → 《php5权威指南》这本书 的几点一些错误

《php5权威指南》这本书 的几点一些错误

时间:2008-07-28

来源:互联网

P102
1.多处$this->后加多了一个$符号,不符合PHP语法规则。

引用P59页:在对象的方法执行的时候,PHP会自动定义一个叫$this的特殊变量,它表示一个对对象本身的引用。通过使用这个变量和->符号,你可以引用该对象其他的方法和属性。例如,你可以通过使用$this->name访问$name属性(注意别在属性的名字前面加$符号)。你也可以用这种方法访问对象的方法;例如,在一个person对象中,你可以通过$this->getName()访问getName()方法。

如:line:17 return $this->$exchange_rate;
正确:return $this->exchange_rate;
line21:$this->$exchange_rate = $new_rate;
正确:$this->exchange_rate = $new_rate;

贴上更正后的:
<?php
  interface Observer{
                function notify($obj);
        }
        class ExchangeRate{
                static private $instance = NULL;
                private $objservers = array();
                private $exchange_rate;
                private function ExchangeRate(){
                }
                static public function getInstance(){
                        if(self::$instance==NULL){
                                self::$instance=new ExchangeRate();
                        }
                        return self::$instance;
                }
                public function getExchangeRate(){
                        return $this->exchange_rate;
                }
                public function setExchangeRate($new_rate){
                        $this->exchange_rate = $new_rate;
                        $this->notifyObservers();
                }
                public function registerObserver($obj){
                        $this->observers[] = $obj;
                }
                function notifyObservers(){
                        foreach($this->observers as $obj){
                                $obj->notify($this);
                        }
                }
        }
        class ProductItem implements Observer{
                public function __construct(){
                        ExchangeRate::getInstance()->registerObserver($this);
                }
                public function notify($obj){
                        if($obj instanceof ExchangeRate){
                                print "Received update!\n";
                        }
                }
        }
        $product1 = new ProductItem();
        $product2 = new ProductItem();
        ExchangeRate::getInstance()->setExchangeRate(4.5);
?>
另外,此例所言,观察者模式是通过一个叫Observer的接口实现的,而此例实际上并不能体现这个要求,笔者认为这个例子有点牵强附会,根本无须这个接口,因为这个接口没有起到什么实质的作用。下面是我去掉Observer后的代码,供参考:
<?php
class ExchangeRate{
static private $instance = NULL;
private $observers = array();
private $exchange_rate;
private function ExchangeRate(){
  
}
static public function getInstance(){
  if(self::$instance == NULL){
   self::$instance = new ExchangeRate();
  }
  return self::$instance;
}
public function getExchangeRate(){
  return $this->exchange_rage;
}
public function setExchangeRate($new_rate){
  $this->exchange_rate = $new_rate;
  $this->notifyObservers();
}
public function registerObserver($obj){
  $this->observers[]=$obj;
}
function notifyObservers(){
  foreach ($this->observers as $obj){
   $obj->notify($this);
  }
}
}
class ProductItem{
public function __construct(){
  ExchangeRate::getInstance()->registerObserver($this);
}
public function notify($obj){
  if ($obj instanceof ExchangeRate ) {
   print "Received update!\n";
  }
}
}
$product1 = new ProductItem();
$product2 = new ProductItem();
ExchangeRate::getInstance()->setExchangeRate(4.5);
?>
效果完全相同,本来就是两个类相互传递信息,干嘛一定要整个接口出来呢?我认为是多此一举。

P112
2.代码第6行:if(date('md'=='0401)){,本页的下面和接下来的一页也出现两次相同的错误。
这样不会运行的,正确的:if(date('md')=='0321'){
贴出改正后的代码:
<?php
if(date('md')=='0321'){
  echo 'A bookstore is one of the only pieces of evidence we have ' .
  'that perple are still thinking. <i>Jerry Seinfeld</i>';
}else{
  echo 'Good morning!';
}
?>

P108
使用映射执行授权模式
所提供的范例代码不能正常运行,我对PHP5的新特性并不是很熟,希望高手指点。范例代码如下:
<?php
class ClassOne{
function callClassOne(){
  print "In Class One\n";
}
}
class ClassTwo{
function callClassTwo(){
  print "In Class Two\n";
}
}
class classOneDelegator{
private $targets;
function __construct(){
  $this->target[] = new ClassOne();
}
function addObject($obj){
  $this->target[] = $obj;
}
function __call($name,$args){
  foreach ($this->target as $obj){
   $r = new ReflectionClass($obj);
   if($method = $r->getMethod($name)){
    if ($method->isPublic() && !$method->isAbstract()){
     return $method->invoke($obj,$args);
    }
   }
  }
}
}
$obj = new classOneDelegator();
$obj->addObject(new ClassTwo());
$obj->callClassOne();
$obj->callClassTwo();
?>
运行后:In Class One
<br />
<b>Fatal error</b>:  Uncaught exception 'ReflectionException' with message 'Method callClassTwo does not exist' in PHPDocument1:23
Stack trace:
#0 PHPDocument1(23): ReflectionClass->getMethod('callClassTwo')
#1 [internal function]: classOneDelegator->__call('callClassTwo', Array)
#2 PHPDocument1(34): classOneDelegator->callClassTwo()
#3 C:\Program Files\Zend\ZendStudio-5.5.1\bin\php5\dummy.php(1): include('PHPDocument1')
#4 {main}
  thrown in <b>PHPDocument1</b> on line <b>23</b><br />
几个疑点:$targets是复数,后面引用又用单数$target,可能是作者手误;$method这个变量从何而来?

P121
echo 'Parameter $name not present and no redirect URL';中的变量名未能反应出来,我想是不合作者本意,应该将引用字符串和变量的符号由单引号改为双引号。
另外如果照着书上的代码运行的话会有错误,(好像是多了{}符引起的)下面是我稍作改动的:
<?php
function sanitize_vars(&$vars,$signatures,$redir_url=null)
{
$tmp = array();
foreach ($signatures as $name=> $sig){
  if (!isset($vars[$name]) && isset($sig['required']) && $sig['required']) {
   if ($redir_url) {
    header("Location:$redir_url");
   }else {
    echo "Parameter $name not present and no redirect URL";
   }
   exit();
  }
  $tmp[$name] = $vars[$name];
  if (isset($sig['type'])) {
   settype($tmp[$name],$sig['type']);
  }
  if(isset($sig['function'])){
   $tmp[$name] = $sig['function']($tmp[$name]);//注意这里的一对{}不能加。否则报错,不符合语法
  }
}
$vars = $tmp;
}
$sigs = array('prod_id'=>array('required'=>true,'type'=>'int'),'desc'=>array('required'=>true,'type'=>'string','function'=>'addslashes'));
sanitize_vars(&$_GET,$sigs);
print_r($_GET);
//调用http://example.com/z.php?prod_id=5&amp;;;;desc=abc"DEF
?>
会输出
Array
(
    [prod_id] => 5
    [desc] => abc\"DEF
)
如果不传递prod_id参数如:
http://example.com/z.php?id=5&desc=abc"DEF
则显示Parameter prod_id not present and no redirect URL
这里我为了能看到运行过程,所以将可以省略的默认参数redir_url省掉了,根据函数的设置会自动设为null

作者: phpcaicai   发布时间: 2008-07-27