《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&;;;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
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&;;;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
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28