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 ?

jwfearn
  • 28,781
  • 28
  • 95
  • 122
Manish
  • 133
  • 9
  • 1
    That means that `explode` is returning an array with only 1 element, so you can't assign it to two variables. – Barmar Mar 10 '15 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. – Matt Mar 10 '15 at 17:30
  • @Barmar, hmm. How do i add the other array?. – Manish Mar 10 '15 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. – Barmar Mar 10 '15 at 17:31
  • Wow. You posted all that code to try to get help with a relatively self-explanatory error message? I would like to refer you to this question - http://stackoverflow.com/questions/12769982/reference-what-does-this-error-mean-in-php I also think a little basic debugging as mentioned by @Barmar is all you need to investigate this problem further. – Mike Brant Mar 10 '15 at 17:32
  • @Barmar, okay, let me try. – Manish Mar 10 '15 at 17:33
  • 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()`. – Barmar Mar 10 '15 at 17:33
  • @MikeBrant, I have been penalized before for not being specific. So had to lay the whole thing down. :P – Manish Mar 10 '15 at 17:34
  • @Barmar, ill do that too. A big thank you. – Manish Mar 10 '15 at 17:35
  • 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. – Mike Brant Mar 10 '15 at 17:40
  • @MikeBrant, :), I'll keep your advice and try not to over do my question/queries. – Manish Mar 10 '15 at 17:44

2 Answers2

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.

Community
  • 1
  • 1
evalarezo
  • 1,134
  • 7
  • 13
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

Misunderstood
  • 5,534
  • 1
  • 18
  • 25