2

Can someone please help me with my code, I can't get it to work.

I have an html input form where I type for example "This is a sample". (data is saved in $_POST['Begriff'])

I want to achive a simple translation, so that the table "drinks" in column "English" is checked for existence of every single word from my input sample sentence and output if found every entry from the corresponding row in one line.

Right now I have two problems: As soon as I add " where English in $wert" to the select statement I get:

Notice: Array to string conversion in nachlesen.php on line 34
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given 

Second Problem: How to I put the sentence together again from the returned results? (Right now I get the output for every found word below each other, instead of one line)

Here is my code:

if ( $_POST['Begriff'] <> "") 
{
$wert = explode(' ',$_POST['Begriff']);
$select = mysql_query ("SELECT * FROM drinks where English in $wert");
while ( $row = mysql_fetch_assoc($select))
  {
  echo ("$row[German] <br>");
  echo ("$row[English]<br>");
  }
}

Thanks in Advance, Daniel

3 Answers3

0
<?php
// premise: the user input in $_POST['Begriff'] is a string like 'This is a sample'
//first split it into single words
// preg_split: \s+ -> one or more whitespaces , PREG_SPLIT_NO_EMPTY -> no "empty" words
// e.g. " Mary had  a      little    lamb" -> array('Mary','had','a','little','lamb')
$words = preg_split('!\s+!', $_POST['Begriff'], -1, PREG_SPLIT_NO_EMPTY);

// now encode each string so that it can be used
// safely as a string-literal within your sql query
// see: sql injection
// this should be:
// $words = array_map(function($e) use($mysql) { return mysql_real_escape_string($e, $mysql); }, $words);
// but apparently you're not storing the resource that is returned by mysql_connect
// mysql_real_escape_string() is applied to each single element in $words
// e.g. array("it's", "been") -> array("it\\'s", "been")
$words = array_map('mysql_real_escape_string', $words);

// now put the string literals into your query 
// format: ... IN ('x','y','z')
// join(",", $words) gives you x,y,z
// join("','", $words) gives you x','y','z
// i.e. the first and the last ' has to be added "manually"
// keep in mind that for an empty array $words this will produce WHERE ... IN ('')
// better test that before even trying to build the query
$query = sprintf("
    SELECT
        German,English
    FROM
        drinks
    WHERE
        English IN ('%s')
", join("','", $words));

// send the query to the MySQL server
// should be: $result = mysql_query($query, $mysql);
$result = mysql_query($query);

// database query -> failure is always an option
if ( !$result ) {
    // add error handling here
}
else {
    // in case there is not a single match in the database
    // your script would print ...nothing
    // I don't like that - but that debatable
    // anway: wrapped in a fieldset
    echo '<fieldset><legend>results:</legends>';
    while( false!==($row=mysql_fetch_array($result, MYSQL_FETCH_ASSOC)) ) {
        printf('%s<br />%s<br />', 
          // just like on the input-side you had to worry about
          // sql injections
          // on the output side you want to avoid
          // that characters from the database can break your html structure
            htmlentities($row['German']),
            htmlentities($row['English'])
        );
    }
    echo '</fieldset>';
}

(script is untested)

VolkerK
  • 95,432
  • 20
  • 163
  • 226
-1
"SELECT * FROM drinks where English in ('". implode("','", $wert) . "')"

EDIT: SQL Injection safe query:

$dsn = 'mysql:dbname=' . $settings['dbname'] . ';host=' . $settings['dbhost'];
$pdo = new PDO($dsn, $settings['dbuser'], $settings['dbpass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

if ( $_POST['Begriff'] <> "") 
{
  $wert = explode(' ',$_POST['Begriff']);

  $placeholders = implode(',', array_fill(0, count($wert), '?'));


  $sth = $pdo->prepare("SELECT * FROM drinks WHERE English in ({$placeholders})");
  $sth->execute($wert);

  $rows = $sth->fetchAll();

  foreach($rows as $row) {
      print_r( $row );
  }

}
Dexa
  • 1,641
  • 10
  • 25
  • there's a risk of sql injection in this statement. –  Mar 27 '14 at 13:20
  • @Howard Better? I was lazy and just posted error in current query, didn't suggest improvements. I guess your downvote was deserved. – Dexa Mar 27 '14 at 13:43
  • i did not downvote btw... your edit looks pretty good. –  Mar 27 '14 at 13:45
-1

why don't you try implode() and convert your array to string??

 if ( $_POST['Begriff'] <> "") 
 {

  //you'l have to replace all "spaces with ',' "
  $pattern = '/\s*,\s*/';
  $replace = "','";
  $wert = preg_replace($pattern, $replace, $_POST['Begriff']);

 $select = mysql_query ("SELECT * FROM drinks where English in ('$wert')");
 while ( $row = mysql_fetch_assoc($select))
   {
   echo ("$row[German] <br>");
   echo ("$row[English]<br>");
   }
 }

ANOTHER SOLUTION (TO PREVENT SQL INJECTION)

 if ( $_POST['Begriff'] <> "") 
 {

  //replace multiple spaces
  $str1 = preg_replace( "/\s+/", " ", $_POST['Begriff'] );
  //convert to array, separated by space
  $arr=explode(" ",$str1);
  $safe_params=array();
  foreach($arr as $param){
     $safe_params[]=mysql_real_escape_string($param);
  }

  $wert=implode("','",$safe_params);

 $select = mysql_query ("SELECT * FROM drinks where English in ('$wert')");
 while ( $row = mysql_fetch_assoc($select))
   {
   echo ("$row[German] <br>");
   echo ("$row[English]<br>");
   }
 }

EDIT

Processing query output according to language

$german_words=array();
while ( $row = mysql_fetch_assoc($select))
{
   $german_words[$row['English']]=$row['Gernam'];
}

//$str1 is having english string
echo "English: ".$str1."<br/>";
echo "German : ";

//$arr is having array of words of $str1
foreach($arr as $eng_word){
   echo $german_words[$eng_word]." ";
}
Ravi Dhoriya ツ
  • 4,435
  • 8
  • 37
  • 48
  • Get the following message with your code: Warning: implode(): Invalid arguments passed in C:\xampp\htdocs\Speisekarte\nachlesen.php on line 38 – ziemlichdunkel Mar 27 '14 at 13:18
  • @user3468443, try my updated answer. It should work now. forgot to replace all space with comma. Sorry for that. – Ravi Dhoriya ツ Mar 27 '14 at 13:36
  • No problem, I'm glad you guys try to help me out, thank you all so much. It seems to work now, but only for single Words in Input, when typing in two Words separatet by space I get no output, just a blank page? – ziemlichdunkel Mar 27 '14 at 14:02
  • @user3468443, got it. replace space with `','` because its string. so `$replace="','" ;` i've updated my answer – Ravi Dhoriya ツ Mar 27 '14 at 14:06
  • a) now your script produces somelike like `... IN ('a,b,c')` but you need `...IN ('a','b','c')` and b) you have to make each single string literal safe for usage in an sql query. edit: you've corrected a) ...yet b) is still open ;-) – VolkerK Mar 27 '14 at 14:06
  • for that we can escape string using `mysql_real_escape_string()` – Ravi Dhoriya ツ Mar 27 '14 at 14:10
  • ....but for each single literal, not the list of literals, i.e. you can't simply apply mysql_real_escape_string($wert) since $wert (currently) contains more than one string literal (from the sql query's point of view). – VolkerK Mar 27 '14 at 14:12
  • ok, got it. let me apply other solution – Ravi Dhoriya ツ Mar 27 '14 at 14:13
  • @VolkerK, how about updated answer? – Ravi Dhoriya ツ Mar 27 '14 at 14:23
  • yes, better. The differences between our two responses now are mostly matter of opinion/style ;-) (except maybe printing the database values without treating them with `htmlentities` - but maybe not even that, because we don't know the encodings used by the client and the mysql connection and ... and ...) – VolkerK Mar 27 '14 at 14:28
  • Wow, that's great It's working now, thank you both. One more Question: How do I get the corresponding entries from the Result into one single Line? (means for 3 Words in the Input Field, the result should be three lines each with it's corresponding entries) – ziemlichdunkel Mar 27 '14 at 14:54
  • corresponding entries means? Can you provide example? – Ravi Dhoriya ツ Mar 27 '14 at 15:00
  • **Now I get:** `This(en) Das(de) is(en) ist(de) sample(en) Beispiel(de)` **I need it like:** `This is sample Das ist Beispiel` – ziemlichdunkel Mar 27 '14 at 15:29
  • My Input: Bier Wein Result for German is now perfect: "German: Bier Wein" But how to I get the other Languages? Also I get this error message: `Notice: Undefined index: Bier in C:\xampp\htdocs\Speisekarte\nachlesen.php on line 67 Notice: Undefined index: Wein in C:\xampp\htdocs\Speisekarte\nachlesen.php on line 67` //$arr is having array of words of $str1 -> the error comes from this codeblock. – ziemlichdunkel Mar 28 '14 at 09:13
  • that undefined error message came because `that word isn't there in your table`. Any ways, don't ask for everything. whatever you required that I solved, further more you'l have to try for your own And then if you are getting any error post here. Don't ask us to do everything. **show your efforts** – Ravi Dhoriya ツ Mar 28 '14 at 09:45
  • **//$arr is having array of words of $str1** – ziemlichdunkel Mar 28 '14 at 10:08
  • **//$str1 is having english string** – Ravi Dhoriya ツ Mar 28 '14 at 10:09
  • look @user3468443, you are executing query `SELECT * FROM drinks where English in ('$wert')` so it will output only matching words whatever you have in table. So array `$german_words` will have only indexes for matching english words (whatever returned by query, trace source properly) – Ravi Dhoriya ツ Mar 28 '14 at 10:12