Php代码显示偏移误差

I am a beginner of smarty php templating system and I'm going through a book Smarty PHP Template Programming. The very first example on chapter 2 is as follows.

In the root folder, we have a file named data.txt with the following information.

Title=> Building Websites with VB.NET and DotNetNuke 3.0 
Image=> 1904811272.jpg 
Author=> Daniel N. Egan 
Description=> A practical guide to creating and maintaining your own website with DotNetNuke, the free, open source evolution of Microsoft's IBuySpy Portal 
Year=> 2005 
Price=> 39.99 

Title=> SSL VPN : Understanding, evaluating and planning secure, web-based remote access 
Image=> 1904811078.jpg 
Author=> Joseph Steinberg, Tim Speed, Simon Jenner 
Description=> A comprehensive overview of SSL VPN technologies and design strategies 
Year=> 2005 
Price=> 49.99 

Title=> Windows Server 2003 Active Directory Design and Implementation=> Creating, Migrating, and Merging Networks 
Image=> 1904811086.jpg 
Author=> John Savill 
Description=> A unique, scenario-based approach to selecting and implementing the best Active Directory design for your environment 
Year=> 2005 
Price=> 59.99

Next step is to retrieve the data from data.txt. For this, a file named get_data.php in the root folder with the following content:

<?php

    class books {

        public $title = array(); 
        public $image = array(); 
        public $author = array(); 
        public $description = array(); 
        public $year = array();
        public $price = array(); 

        private $filename = "data.txt";

        //class constructor
        function __construct()
            {
                //get the lines as an array
                $i=-1;
                $lines = file($this->filename);
                // strip "
" at the end of each array
                // get each variable in an array

                foreach ( $lines as $line) {
                if (strlen($line) > 2) {

                    $line = rtrim($line);

                    list($what, $content) = explode("=>", $line);

                    if ($what == "Title") {
                        $i++;
                        $this->title[$i]=$content;
                        }
                    elseif ($what == "Image") {
                        $this->image[$i]=$content;
                        }
                    elseif ($what == "Author") {
                        $this->author[$i]=$content;
                        }
                    elseif ($what == "Description") {
                        $this->description[$i]=$content;
                        }
                    elseif ($what == "Year") {
                        $this->year[$i]=$content;
                        }
                    elseif ($what == "Price") {
                        $this->price[$i]=$content;

                        };
                        };
                    };

                } // end constructor

                } // end GetData

The business Logic Layer is responsible for data validation from the business point of view. In this example, we will apply a ten percent discount for the books published in 2005 and a twenty percent discount for books published in 2004. We need to create a file in the root folder named books.php as shown

<?php
class bo_books {
//public
public $title = array();
public $image = array();
public $author = array();
public $description = array();
public $year = array();
public $price = array();
public $discount = array();
public $discounted = array();
//private
protected $DataObject;
function __construct()
{
$this->DataObject = new books();
}
public function apply_discount()
{
$this->title = $this->DataObject->title;
$this->image = $this->DataObject->image;
$this->author = $this->DataObject->author;
$this->description = $this->DataObject->description;
$this->year = $this->DataObject->year;
$this->price = $this->DataObject->price;
$j = 0;
foreach($this->year as $year)
{
if ($this->year[$j] == '2004')
$this->discount[$j] = '20';
elseif ($this->year[$j] == '2005')
$this->discount[$j] = '10';
$this->discounted[$j] = intval($this->price[$j] * (100 - $this->discount[$j]) ) / 100 ;
$j++;
};
} // end function apply_discount()
} // end class bo_books

The Presentation Layer: First, we need to pass the variables from the Business Logic Layer to the Presentation Layer. In the root folder, we create a file named index.php like this:

<?php

require("libs/Smarty.class.php");
require_once("get_data.php");
require_once("books.php");

$book = new bo_books();
$book->apply_discount();

$smarty = new Smarty; 

$smarty->assign("book",$book);

$smarty->display('index.tpl');

?>

Next, we create an index.tpl file in the templates folder

<html>
<head> <title> Site Architecture Example </title>
</head>
<body>
<table border="0" width="100%">
<tr>
<td align="left">
<a href="http://www.packtpub.com">
<img src="images\Packt.png" border="0">
</a>
<img src="images\focused.gif">
</td>
<td>
<h1> Chapter 2 Example </h1>
</td>
</tr>
</table>
<br>
Here are the books in a two-column table :
<br> <br>
<table border="1" width="100%">
{section name=tbl loop=$book->title}
{if %tbl.index% is not odd}
<tr>
{/if}
<td align="left">
<table>
<tr>
<td>
<img src="images\{$book->image[tbl]}" width="220">
</td>
<td valign="top">
<font size=+1><b> {$book->title[tbl]} </b></font><br>
<font size=-1 color=blue><b> {$book->author[tbl]} </b></font><br>
{$book->description[tbl]} <br>
Year: {$book->year[tbl]} <br>
<font size=-1>Cover Price: <s>${$book->price[tbl]}</s></font> <br>
Our Price: ${$book->discounted[tbl]}
<font color=red> save {$book->discount[tbl]} % </font>
</td>
</tr>
</table>
</td>
{if %tbl.index% is odd}
</tr>
{/if}
{/section}
</table>
</body>
</html>

As I run the program

Notice: Undefined offset: 1 in C:\wamp\www\MyCode\get_data.php on line 28" is diplayed.

The line 28 on get_data.php is

list($what, $content) = explode("=>", $line);

Can anyone suggest something or even help ?

As Barmar said, the problem is you have an array with less or more than two elements in some point of your file. See line 15 of data.txt and you will find a second =>, so I guess that is the problem.

Try to fix the line 28 of get_data.php to this:

list($what, $content) = array_pad(explode('=>', $line, 2), 2, null);

So you will ALWAYS have two elements in your array.

Based on this answer.

The value of $line is 1.

$str = 1;
list($what, $content) = explode("=>", $str);

Gives this notice:

Notice: Undefined offset: 1 in test.php on line 7