3

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 "\n" 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 ?

11
  • 1
    That means that explode is returning an array with only 1 element, so you can't assign it to two variables. Commented Mar 10, 2015 at 17:29
  • Hey Manish, This is a very thorough post which is good, but in this case, we really need a broken down example. It seems like the only thing that's relevant here is your get_data.php. Your bo, smarty template, and everything else has nothing to do with your problem. Can you break it down to a solid specific example. Paste the output of var_dump($lines); before your loop. Commented Mar 10, 2015 at 17:30
  • 1
    This would happen if $line doesn't have => on it. Put var_dump($line); and see what it shows when the error happens. Commented Mar 10, 2015 at 17:31
  • 1
    I suspect the problem is that the blank lines between the titles aren't really empty, they have a bunch of spaces on them. Try trimming before testing strlen(). Commented Mar 10, 2015 at 17:33
  • 1
    @Manish Fair enough. I think you went too far this time :) You really only need parts of the code that are relevant to the the problem. I don;t think the display layer makes any difference here. It is just whatever happenson get_data.php line 28 and upstream call stack, including your data source. Commented Mar 10, 2015 at 17:40

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.