Jump to content


Photo

illegal string offset


  • Please log in to reply
6 replies to this topic

#1 safety

safety

    Member

  • Members
  • PipPip
  • 16 posts

Posted 19 September 2012 - 10:40 AM

Evening guys, I've got a slight problem. I'm building a news entry system on my website.

The links to the content work fine, however, when I go to a page (for example id=3) the links in the "righttop" section display as:

"Warning: Illegal string offset 'title' in C:\xampp\htdocs\blues\index.php on line 79"

and the links there don't work.

Basically links in the "topright" section work fine unless i'm on page with "id=" ; where I get the error messages.

Here's the code for my index.php so you can see what I mean by "topright" :P

<!DOCTYPE HTML>
<html lang = "en">
<?php
/*
* Include the necessary files
*/
include_once 'inc/functions.inc.php';
include_once 'inc/db.inc.php';

// Open a database connection
$db = new PDO(DB_INFO, DB_USER, DB_PASS);
/*
 * Figure out what page is being requested (default is news)
* Perform basic sanitization on the variable as well
*/
if(isset($_GET['page']))
{
	$page = htmlentities(strip_tags($_GET['page']));
}
else
{
	$page = 'news';
}
// Determine if an entry ID was passed in the URL
$id = (isset($_GET['id'])) ? (int) $_GET['id'] : NULL;

// Load the entries
$e = retrieveEntries($db, $id);

// Get the fulldisp flag and remove it from the array
$fulldisp = array_pop($e);
// Sanitize the entry data
$e = sanitizeData($e);

?>
<head>
	<title>The Blues Bar | Free Live Music Venue</title>
	<meta charset = "UTF-8" />
	<link 	rel = "stylesheet"
			type = "text/css"
			href = "style.css" />
</head>

	

<body>

	<header>
		Free live music 7 days a week | A selection of guest ales
	</header>
	
	<div id="wrapper">

		
		
		<nav class="clearfix">
				<a rel="external" href="index.php" class="button">Home</a><a rel="external" href="index.php?page=news" class="button">News</a><a rel="external" href="index.php?page=giglistings" class="button">Gig Listings</a><a rel="external" href="index.php?page=venue" class="button">The Venue</a><a rel="external" href="index.php?page=photos" class="button">Photos</a><a rel="external" href="index.php?page=contact" class="button">Contact</a>
				<a id="twit" href="#"></a><a id="fb" href="#"></a>
		</nav>
		





		<div id="topcontent" class="clearfix">  
            <section id="lefttop">  
                <h1>Upcoming Gigs</h1><p>Sat 15th Sept - Jed ThomasMon 17th Sept - Jam Night</p>
            </section>  
              
            <section id="righttop">  
                <h1>Recent News</h1><p>
                
                <?php 
                foreach($e as $entrynav) {
							?>
					<p>
					<a href="?page=news&id=<?php echo $entrynav['id'] ?>">
					<?php echo $entrynav['title'] ?>
					</a>
					</p>
					<?php
					} // End the foreach loop
					?>
                
                
                 
            </section>  
        </div>  
		
		<div id="core" class="clearfix">  
            <section id="left">  
            
            
            
            
            
            <div id="entries">
            	<?php
				/*
				* Very basic security measure to ensure that
				* the page variable has been passed, enabling you to
				* ward off very basic mischief using htmlentities()
				*/
				if(isset($_GET['page'])) {
				$id = htmlentities($_GET['page']);
				} else {
				$page = NULL;
				}
				switch($page) {
				case 'giglistings':
				echo "
				<h1> Gig Listings </h1>
				<p> Here are the gig listings, under construction </p>";
				break;
				
				case 'news' :
					// If the full display flag is set, show the entry
					
					// If the full display flag is set, show the entry
					if($fulldisp==1)
					{
					?>
					<h2> <?php echo $e['title'] ?> </h2>
					<p> <?php echo $e['created']?><?php echo $e['entry'] ?> </p>
					<p class="backlink">
					<a href="./">Back to Latest Entries</a>
					</p>
					<?php
					} // End the if statement
					// If the full display flag is 0, format linked entry titles
					else
					{
						// Loop through each entry
						foreach($e as $entry) {
							?>
					<p>
					<a href="?page=news&id=<?php echo $entry['id'] ?>">
					<?php echo $entry['title'] ?>
					</a>
					</p>
					<?php
					} // End the foreach loop
					} // End the else
				break;
				
				case 'venue':
				echo "
				<h1> Venue </h1>
				<p> This is the Blues Bar venue page, with all the information about the venue. </p>";
				break;
				
				case 'photos':
				echo "
				<h1> Photos </h1>
				<p> Will be built at a later date when I have 100 years spare </p>";
				break;
				
				case 'contact':
				echo "
				<h1> Contact </h1>
				<p> Contact us for a gig! </p>";
				break;
				
				/*
				* Create a default page in case no variable is passed
				*/
				default:
				echo "
				<h1> Home </h1>
				<p>
				Lots of intresting indroductions to the blues bar etc. </p>";
				break;
				}
				?>
				</div>
            
            </section>  
              
            <section id="right">  
                
            </section>
			
        </div> 
		
		<footer>  
			<p>The Blues Bar</p>  
		</footer>  	
	</div>  
	
	
</body>  
</html>  ]


and here is my functions page: functions.inc.php

<?php
function retrieveEntries($db, $id=NULL)
{
	/*
	* If an entry ID was supplied, load the associated entry
	*/
	if(isset($id))
	{
		$sql = "SELECT title, entry , created
		FROM news
		WHERE id=?
		LIMIT 1";
		$stmt = $db->prepare($sql);
		$stmt->execute(array($_GET['id']));
		// Save the returned entry array
		$e = $stmt->fetch();
		// Set the fulldisp flag for a single entry
		$fulldisp = 1;
	}
	/*
	* If no entry ID was supplied, load all entry titles for the page
	*/
	else
	{
		$sql = "SELECT id, title, entry, created
		FROM news
		ORDER BY created DESC";
		$stmt = $db->prepare($sql);
		$stmt->execute(array($id));
		$e = NULL; // Declare the variable to avoid errors
		$result = $db->query($sql);
		// Loop through returned results and store as an array
		while($row = $stmt->fetch()) {
			$e[] = $row;
		}
		// Set the fulldisp flag for multiple entries
		$fulldisp = 0;
		/*
		* If no entries were returned, display a default
		* message and set the fulldisp flag to display a
		* single entry
		*/
		if(!isset($e))
		{
			$fulldisp = 1;
			$e = array(
			'title' => 'No Entries Yet',
			'entry' => '<a href="/admin.php">Post an entry!</a>'
			);
		}
	}
		// Add the $fulldisp flag to the end of the array
		array_push($e, $fulldisp);
		return $e;
}

function sanitizeData($data)
{
	// If $data is not an array, run strip_tags()
	if(!is_array($data))
	{
		// Remove all tags except <a> tags
		return strip_tags($data, "<a>");
	}
	// If $data is an array, process each element
	else
	{
		// Call sanitizeData recursively for each array element
		return array_map('sanitizeData', $data);
	}
}

?>


I don't know how easy it will be for someone to know what's going on with my code and to help me but I thought there's no harm in asking.
Thanks for any help in advance

#2 Jessica

Jessica

    This is not my name.

  • Gurus
  • 8,982 posts
  • LocationDallas, TX
  • Age:26

Posted 19 September 2012 - 10:41 AM

Woaaaaa.
Use code tags (the # button) and post only the relevant section.

If your page link end in id= with no number, you need to capture the id before trying to use it and make sure it exists. On both the page that uses id, and the page that prints the links.
My goal in replying to posts is to help you become a better programmer, including learning how to debug your own code and research problems. For that reason, rather than posting the solution, I reply with tips and hints on how to find the solution yourself. See below for useful links when you get stuck.

How to Get Good Help: How to Ask Questions | Don't be a help vampire
Debugging Your Code: Debugging your SQL | What does a php function do? | What does a term mean? | Don't see any errors?
Things You Should Do: Normalize Your Data | use print_r() or var_dump()
Lulz: "Functions should not have side effects." - trq

Please take a look at my new PHP/Web Dev blog: The Web Mason - Thanks!!

#3 kicken

kicken

    Wiser? Not exactly.

  • Gurus
  • 2,702 posts
  • LocationBonita, FL

Posted 19 September 2012 - 10:47 AM

If you specify an ID, your function only returns a single-level array (one specific entry) with the column names as keys.  Your small bit of code for the nav menu assumes that it will be a two-level array though (a list of entries).

As a result when you try and foreach through it, your assigning a string value you your $entrynav (as in $entrynav="Some post title";) variable then trying to access $entrynav['title'] which is obviously not right since strings don't have keys.

You need to either make your function always return a list of entries (even if it's a list of one) or add your $fulldisp check to the nav menu part as well.
Recycle your old CD's, don't trash them!
Did I help you out?  Feeling generous? I accept tips via Paypal or Bitcoin @ 14mDxaob8Jgdg52scDbvf3uaeR61tB2yC7

#4 safety

safety

    Member

  • Members
  • PipPip
  • 16 posts

Posted 19 September 2012 - 10:57 AM

Sorry about the code tags, sorted it now.

That makes sense, I'll have a go at that later, thanks for that.

#5 safety

safety

    Member

  • Members
  • PipPip
  • 16 posts

Posted 19 September 2012 - 04:27 PM

I've had a go at what you suggested. Adding the $fulldisp check simply mirrors what I have in the main content box in the "topright" box. What I want is the topright box to display a list of entries, regardless of what page i'm on (regardless of if my address returns an "id" value or not).

I'm not quite sure how to edit my function so that if the "id" value is present it returns a list of values (which need to be a singular list of values).


#6 safety

safety

    Member

  • Members
  • PipPip
  • 16 posts

Posted 20 September 2012 - 04:43 AM

Update, i've decided to make a functions that always returns an array (or so I thought)

function retrieveEntriesAlways($db, $id=NULL)
{
	$sql = "SELECT id, title, entry, created
		FROM news
		ORDER BY created DESC";
	$stmt = $db->prepare($sql);
	$stmt->execute(array($id));
	$f = NULL; // Declare the variable to avoid errors
	$result = $db->query($sql);
	// Loop through returned results and store as an array
	while($row = $stmt->fetch()) {
		$f[] = $row;
	}
        return $f;
	
}

I added this to my index.php
$f = retrieveEntriesAlways($db, $id);

and now i'm sorted, thanks

#7 Christian F.

Christian F.

    Advanced Member

  • Staff Alumni
  • 3,106 posts
  • LocationNorway

Posted 20 September 2012 - 05:43 AM

NULL is not an array, which means it'll still give an error if you don't return any rows.
Keeping it simple.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Cheap Linux VPS from $5
SSD Storage, 30 day Guarantee
1 TB of BW, 100% Network Uptime

AlphaBit.com