Problem with foreach

Hi there, I’m trying to make the function below work, but I get a little bit confused.

<?php
	                $stmt_word1 = $auth_user->runQuery("SELECT * FROM words WHERE word_id = '".$word_id."'");
                    $stmt_word1->execute();
                    $wordLangRows=$stmt_word1->fetchAll(PDO::FETCH_ASSOC);
	            
	                $counter = 1;
	                foreach($wordRow as $k => $v)
            		    {
            		        if($v['word_name'] != $word_id)
            		        {
				?>
	            <img src="images/words/pictures/<?php echo $v['word_name']; ?>.png" alt="картинка на <?php echo $v['word_name']; ?>">
	            <?php
				            }
            		    }
				?>

What I’m trying to do is to add a picture to words that have a picture inside the “images/words/pictures/” map, but it shows me then also the words that does not have one (see picture).

Is it posibble to tell this code to show only the picture, with the same name as the word, instead of pictures that does not exist? If I click on the word language, for example, I get the picture of the lamb, but the word language has no picture so the img tag needs to be hidden then. Thank you kindly!

You could use file_exists to find out if there is a picture for that word.

if(file_exists($_SERVER["DOCUMENT_ROOT"] . '/images/words/pictures/'.$v['word_name'])) {
    ... // Show image
}

[off-topic]

$stmt_word1 = $auth_user->runQuery("SELECT * FROM words WHERE word_id = '".$word_id."'");

It would probably be a good idea to use a prepared statement here.

1 Like

Does this function need to be put inside the img tag, or does the img tag need to be placed between the brackets? Because either way it does not work.

You would display the image if the condition returns true, which meand the file does exist.

There is an error, I forgot to append the file extension.

if(file_exists($_SERVER["DOCUMENT_ROOT"] . '/images/words/pictures/'.$v['word_name'] . '.png'))  { // show image }

So, both ways are working, but again I get the picture in every single word. Does this code tells the picture to be hidden if there is no picture with the name language.png, for example?

<?php if(file_exists($_SERVER["DOCUMENT_ROOT"] . '/images/words/pictures/'.$v['word_name'] . '.png')) { echo '<img src="/images/words/pictures/'.$v['word_name'] . '.png"/>'; } ?>
<img src="<?php if(file_exists($_SERVER["DOCUMENT_ROOT"] . '/images/words/pictures/'.$v['word_name'] . '.png')) { echo '/images/words/pictures/'.$v['word_name'] .'.png'; } ?>">

The file_exists() function will return true if the file name (and path) given to the function does exist.
So putting it in an if statement will carry out the code in the brackets if the file does exist.
If there is no such file, the code within the brackets will be ignored.

So if the code within the brackets echos out the <img> element, that will only happen if the file with that name exists.

I understand that, but in both ways the picture does appear in every single word.

That would suggest that there is an image for every word. :confused:

This is the whole code.

<?php
	                $stmt_word1 = $auth_user->runQuery("SELECT * FROM words WHERE word_id = '".$word_id."'");
                    $stmt_word1->execute();
                    $wordLangRows=$stmt_word1->fetchAll(PDO::FETCH_ASSOC);
	            
	                $counter = 1;
	                foreach($wordRow as $k => $v)
            		    {
            		        if($v['word_name'] != $word_id)
            		        {
				?>
				<?php if(file_exists($_SERVER["DOCUMENT_ROOT"] . '/images/words/pictures/'.$v['word_name'] . '.png')) { echo '<img src="/images/words/pictures/'.$v['word_name'] . '.png"/>'; } ?>
	            <?php
				            }
            		    }
				?>

And in the “/images/words/pictures/” map I do have only one image inside it.

Because debugging takes up the majority of coding time, may I suggest taking advantage of verbose scripting. This may add a fraction of a millisecond to the processing time which is neglible compared to the time spent debugging.

<?php

// DEBUGGING ROUTINE
function fred($val, $verbose=FALSE)
{
  echo '<pre>'; // prettify output
    if($verbose)
    {	
    	var_dump($val);
    }else{
    	print_r($val);
    }//endif; 
  echo '</pre>';
}// 

$sql = 'SELECT * FROM words WHERE word_id = "' .$word_id .'"';
// fred($sql); die;

$stmt_word1 =  $auth_user -> runQuery( $sql );
$stmt_word1 -> execute();

$wordLangRows = $stmt_word1->fetchAll(PDO::FETCH_ASSOC);
// fred($wordLangRows); die;

// $counter = 1; NOT USED
foreach($wordRow as $k => $v)
{
  // fred( $v ); die;
  if($v['word_name'] !== $word_id) // best to have more exact comparison
  {
  	$img = '/images/words/pictures/' .$v['word_name'] . '.png';
  	// fred($img);
  	$ok  = file_exists( $_SERVER['DOCUMENT_ROOT'] .$img );
	if( $ok )
	{ 
	  echo '<img src="' .$img .'"/>';
	}
  }//endif 
}//endforeach

// not required ? >

The if logic is backwards and no idea where $wordRow array is coming from - try this:

<?php
error_reporting(E_ALL);  ini_set('display_errors', 'On');  // first line of defense

  // assuming $word_id is set/sanitized - Not specified in your code snippet...
$stmt_word1 = $auth_user->runQuery("SELECT word_id FROM words WHERE word_id = '". $word_id. "'");
$stmt_word1->execute();
$wordLangRows = $stmt_word1->fetchAll(PDO::FETCH_ASSOC);
  // echo '<pre>'. print_r($wordLangRows, 1). '</pre>';  /* remove // to show returned data */

foreach($wordLangRows as $k => $v) {  // not $wordRow !!! - would be caught by error reporting
  $img = 'images/words/pictures/'. $v['word_name']. '.png';  // echo $img. '<br />';
    // if the word_id is in the database AND it has a picture, output the HTML
  if ($word_id == $v['word_name'] && file_exists($img)) {
    echo '<img src="'. $img. '" alt="'. ucfirst($v['word_name']). '" />';
  }  // end if
}  // end foreach

Your function does not show the picture at all.

Works good, except the appearing of the picture in every word. That did not change.

It’s an example snippet to adapt, I have no way to test it. You aren’t posting all the code needed (such as where $word_id is coming from, nor what the database column names are). Maybe replace $v[‘word_name’] with $v[‘word_id’] in the foreach loop?

Basic logic is correct thought - if $word_id is ‘lamb’ and ‘lamb’ is contained in one of the database rows and images/words/pictures/lamb.png exists, then and only then the HTML img tag will be output.

If you post the actual array row that matches (from uncommmenting the // echo) we could know the actual value to match against, Example was to show only retrieve the values from the database needed: SELECT word_id instead of *

None of the earlier examples could possibly work, since $wordRow is never created anywhere!

That’s where the error reporting comes in handy :wink:

It appears as though your SQL statement is asking for ONLY words that match $word_id.

I think the test for an image in the foreach loop is incorrect and wants changing to ONLY match the images that have a corresponding word.

It is best to use the exact === match but trim(…) may be required to remove spaces.

I would have temporarily removed the image rendering and displayed the results of the if test to ensure the data is correct:

foreach($wordRow as $k => $v)
{
  // fred( $v ); die;
  if($v['word_name'] === $word_id) // best to have more exact comparison
  {
  	echo '<br><br>';
  	echo '$v["word_name"] ==> ' .$v["word_name"]; 
  	echo '<br>';
  	echo '$word_id ==> ' .$word_id; 
  	
  	/* 
  	$img = '/images/words/pictures/' .$v['word_name'] . '.png';
  	// fred($img);
  	$ok  = file_exists( $_SERVER['DOCUMENT_ROOT'] .$img );
		if( $ok )
		{ 
	  	echo '<img src="' .$img .'"/>';
		}
	*/

  }//endif 

}//endforeach

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.