Nikola Sivkov
Nikola Sivkov

Reputation: 2852

1 character only foreach loop result in PHP

Hello i have this foreach loop that gives weird result , it displays only the first character form the db record

<?php
$result2 = mysql_query("SELECT id,fp_thumb,title FROM media") or die(mysql_error());
$data2 = mysql_fetch_array($result2) or die(Mysql_error());

foreach ($data2 as $val) {

  echo '<li><a href="media.php?id='.$val['id'].'"><img src="'.$val['fp_thumb'].'" alt="'.$val['title'].'" /></a></li>';
}
?>

and this is my DB structure

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for media
-- ----------------------------
CREATE TABLE `media` (
  `id` int(11) NOT NULL auto_increment,
  `thumb` varchar(500) NOT NULL,
  `url` varchar(500) NOT NULL,
  `fp_thumb` varchar(500) NOT NULL,
  `title` varchar(500) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records 
-- ----------------------------
INSERT INTO `media` VALUES ('1', '22', 'http://goeshere.com', '/images/slideshow/ctmbs.jpg', 'Test 1');
INSERT INTO `media` VALUES ('2', '2', 'http://goeshere1.com', '/images/slideshow/hitlex.jpg', 'test 2');
INSERT INTO `media` VALUES ('3', '3 ', 'http://goeshere2.com', '/images/slideshow/tsord.jpg', 'test 3');

Any info would be usefull Thanks in advance and cheers ^^

Upvotes: 3

Views: 3458

Answers (4)

A B S
A B S

Reputation: 15

I suffered from the same output. Later, found the mistake I did. I have initialized that same variable before as a string. Using a new variable solved the problem. Help found on: http://www.sitepoint.com/forums/showthread.php?259452-Only-outputting-first-character-of-array

Upvotes: 0

Pascal MARTIN
Pascal MARTIN

Reputation: 401032

From the code, I would say that $data2 represents the data of 1 line from the DB.

So, it should be $data2 that contains what you want to display.

Your foreach loop is useless : if you want to display the data from 1 line, you can just use $data2 directly.


If you want to go line by line, you must not iterate over $data2, but loop while mysql_fetch_array returns data.

Something like this, I'd say :

$result2 = mysql_query("SELECT id,fp_thumb,title FROM media") or die(mysql_error());
while ($data2 = mysql_fetch_array($result2)) {
    echo '<li><a href="media.php?id='.$data2['id'].'"><img src="'.$data2['fp_thumb'].'" alt="'.$data2['title'].'" /></a></li>';
}

Also, you might want to escape the data your are outputing, to make sure you don't have any kind of HTML/javascript injection -- at least in the src and title, I'd say ; for that, you can use htmlspecialchars

Your echo would, then, probably look like this :

echo '<li><a href="media.php?id='
    . $data2['id']
    . '"><img src="'
    . htmlspecialchars($data2['fp_thumb'])
    . '" alt="'
    . htmlspecialchars($data2['title'])
    . '" /></a></li>';

(I considered id is an integer, auto-incremented or something like that, so not much of a risk)


Edit after seeing the comment on another answer

With what you first used :

$data2 is an associative array, that looks like this :

array
  'id' => int 152
  'title' => string 'this is the title' (length=17)
  'fp_thumb' => string 'http://...../' (length=13)

Which means the foreach will loop three times, and $val will be :

int 152
string 'this is the title' (length=17)
string 'http://...../' (length=13)

(One value for each iteration)

ie, $val is not an array is a scalar value.


When you do that :

$a = 152;
var_dump($a['id']);

you get

null

When doing

$a = 'this is the title';
var_dump($a['id']);

you get :

string 't' (length=1)

ie, you only get the first character when using array-access on a string, with a key that is a string.


Note that array-access on a string, with a numeric key, is used to access one character of the array :

$a = 'this is the title';
var_dump($a[3]);

gets you :

string 's' (length=1)


For more informations, see the manual page about string, especially String access and modification by character, which states :

Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array brackets, as in $str[42]. Think of a string as an array of characters for this purpose.

And :

Non-integer types are converted to integer.

And converting 'title' to an integer gives 0 ; so, you get the first character of the string.


Hope this helps, and you understood "why" ;-)

Upvotes: 4

Rob Knight
Rob Knight

Reputation: 8782

I think what you're trying to do is this:

$result2 = mysql_query("SELECT id,fp_thumb,title FROM media") or die(mysql_error());

while($data2 = mysql_fetch_array($result2)) {
    echo '<li><a href="media.php?id='.$data2['id'].'"><img src="'.$data2['fp_thumb'].'" alt="'.$data2['title'].'" /></a></li>';
}
?>

This displays all of the records in the table. Is that what you're trying to do?

The important point here is that mysql_fetch_array only retrieves a single record, and you need to call it multiple times to retrieve multiple records. It will eventually return FALSE when there are no more records to fetch.

Upvotes: 2

Zed
Zed

Reputation: 57658

You should iterate over $results with mysql_fetch_array as it only fetches one result for each call:

while ($val = mysql_fetch_array($result2, MYSQL_ASSOC)) {
  echo '<li><a href="media.php?id='.$val['id'].'"><img src="'.$val['fp_thumb'].'" alt="'.$val['title'].'" /></a></li>';
}

Upvotes: 0

Related Questions