1

I have got a string ($string) from which I extract the username for querying mysql database. I am using the php explode function like the code below.

( $number is the total number of id in the string).

For each loop I get the username of Mysql database but the problem is that my query doesn't accept it.

For example, I get Marta (shown on my display from echo $usercut) but the $query doesn't work and I don't get the echo $row['email'];.

The funny thing is that if I change $usercut typing the string "Marta" $usercut= "Marta"; it works!!!!!! and I get the echo $row['email'];.... It is something that makes me mad... Does someone know if the php explode function add some hidden character to the string?

<?php



$string = "<tr id='0r'>Marta</tr0r><tr id='1r'>Paolo</tr1r><tr id='2r'>Carlo</tr2r><tr id='3r'>Esther</tr3r><tr id='4r'>Franceso</tr4r><tr id='5r'>Charles</tr5r>";

str_replace("id=","id=",$string,$number);

for($i=0; $i<= $number; $i++)
{

     $start = "<tr id='".$i."r'>";
     $end = "<\/tr".$i."r>";
     $startHadCut = explode($start, $string) ;
     $endHadCut = explode($end,$startHadCut[1]);    

    echo   $usercut = $endHadCut [0];

$query = "SELECT * FROM `Database` WHERE username = '".mysqli_real_escape_string($link, $usercut)."' LIMIT 1";   
        $row = mysqli_fetch_array(mysqli_query($link, $query));

        echo $row['email'];
}

?>
giuseppe
  • 105
  • 9
  • When I run your for loop it doesn't return what you're expecting. I am not getting a clean name on each loop with `echo $usercut = $endHadCut [0];` – Jay Blanchard Oct 27 '17 at 20:06
  • When all you know is `explode`, every string might potentially become dynamite. – mario Oct 27 '17 at 20:09
  • I didn't write the code to get $number. str_replace("id=","id=",$string,$number);// number of contacts – giuseppe Oct 27 '17 at 20:10
  • 2
    What is ``? Your string looks almost like HTML, except that makes it invalid -- it should just be `` – Barmar Oct 27 '17 at 20:15
  • Also, use prepared queries, don't build your query using concatenations. – Casimir et Hippolyte Oct 27 '17 at 20:16
  • I agree with Barmer about not using explode for this. But your code should work as posted, if you remove the backslash from `$end`. There's no need to escape the slash. – jh1711 Oct 27 '17 at 20:16
  • I LOVE YOU jh1711!!!!! it was that backslash!!!!! THANKSSSSSS – giuseppe Oct 27 '17 at 20:24
  • Additionally, if you output something to the browser, remember to use `HTMLEntities()` or print it as plain text. Otherwise you'll get `Marta`, and the browser will show you `Marta` - and you won't immediately see why "Marta" is not in the database. Marta is; `Marta` isn't. – LSerni Oct 27 '17 at 20:35
  • If you have control of the HTML here, you should rewrite. You then could use a parser and this whole process is much easier. – chris85 Oct 27 '17 at 20:40
  • Thanks to everyone, you guys are amazing!! – giuseppe Oct 28 '17 at 09:56

2 Answers2

1

Instead of using explode() you can get results more cleanly using some regex to do what you want, because explode() might not return what you expect.

Here is the regex I used, with look aheads and look behinds to get the text between the tags.

(?<=\'>)(.*?)(?=<\/tr)

Notice that I did not have to identify which tag was used, only the part of the tag relevant to getting the text from between them.

Using preg_match_all() this returns the following array:

Array
(
    [0] => Array
        (
            [0] => Marta
            [1] => Paolo
            [2] => Carlo
            [3] => Esther
            [4] => Franceso
            [5] => Charles
        )

    [1] => Array
        (
            [0] => Marta
            [1] => Paolo
            [2] => Carlo
            [3] => Esther
            [4] => Franceso
            [5] => Charles
        )

)

Now I can select a matched array and loop through them for the result:

$string = "<tr id='0r'>Marta</tr0r><tr id='1r'>Paolo</tr1r><tr id='2r'>Carlo</tr2r><tr id='3r'>Esther</tr3r><tr id='4r'>Franceso</tr4r><tr id='5r'>Charles</tr5r>";
$pattern = '/(?<=\'>)(.*?)(?=<\/tr)/';
preg_match_all($pattern, $string, $matches);
foreach($matches[0] as $user) {
    $query = "SELECT * FROM `Database` WHERE username = '".mysqli_real_escape_string($link, $user)."' LIMIT 1";   
    $row = mysqli_fetch_array(mysqli_query($link, $query));
    echo $row['email'];
}    

WARNING

Learn about prepared statements for MySQLi. Even escaping the string is not safe!

Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119
0

Use preg_match_all() to match the pattern in your data, rather than explode().

preg_match_all("#<tr id='(\d+)'>(.*)</tr\\1>#", $string, $matches);
foreach ($matches[2] as $usercut) {
    ...
}
Barmar
  • 741,623
  • 53
  • 500
  • 612