0

Well i got a very odd problem. Im trying to import the data from the WoW armory, and in the process add this information to my own database underneath a table called user.

Now im checking while adding new members also if all the information about the current members is still correct using (keep in mind fixing all the sql injection problems is something i will do after this):

@$json = file_get_contents("http://$region.battle.net/api/wow/guild/$realm/$guild?fields=members,achievements");
if($json == false)
{
throw new Exception("Failed To load infomation. check setup options");
} 
$decode = json_decode($json, true);

foreach($decode['members'] as $p) {
    $mrank = $p['rank'];
    $mname = $p['character']['name'];
    $mclass = $p['character']['class'];
    $mrace = $p['character']['race'];
    $mlevel = $p['character']['level'];
    $mgender = $p['character']['gender'];

    $check = mysql_query("SELECT * FROM user WHERE charactername='$mname'");
    if($check == false)
    { 
        die("Sql query failed"); 
    }
    if(mysql_num_rows($check) != 0)
    {
        if($mlevel !== $check['level'])
        {
            mysql_query("UPDATE user SET level='$mlevel' WHERE charactername='$mname'");
            $uCount = $uCount + 1; 
            echo "level $mname<br />"; 
        }
        if($mclass !== $check['class'])
        {
            mysql_query("UPDATE user SET class='$mclass' WHERE charactername='$mname'");
            $uCount = $uCount + 1; 
            echo "class $mname<br />"; 
        }
        if($mrace !== $check['race'])
        {
            mysql_query("UPDATE user SET race='$mrace' WHERE charactername='$mname'");
            $uCount = $uCount + 1; 
            echo "race $mname<br />"; 
        }
        if($mgender !== $check['gender'])
        {
            mysql_query("UPDATE user SET gender='$mgender' WHERE charactername='$mname'");
            $uCount = $uCount + 1; 
            echo "gender $mname<br />"; 
        }
        if($mrank !== $check['rank'])
        {
            mysql_query("UPDATE user SET rank='$mrank' WHERE charactername='$mname'");
            $uCount = $uCount + 1; 
            echo "rank $mname<br />"; 
        }
    $pCount = $pCount + 1;

    }   
    else
    {
    //add new user otherwise
        $sql="INSERT INTO user (charactername, class, race, level, gender, rank) VALUES ('$mname','$mclass','$mrace','$mlevel','$mgender','$mrank')";
        $nCount = $nCount + 1;
        if (!mysql_query($sql,$con))
            {
            die('Error: ' . mysql_error());
            }
    }
}
    echo "$nCount new members added.<br />";
    echo "$pCount member(s) already existed.<br />";
    echo "$uCount member(s) got updated <br />";

But now is the problem, using this code the update part so all the:

if($mlevel !== $check['level'])
        {
            mysql_query("UPDATE user SET level='$mlevel' WHERE charactername='$mname'");
            $uCount = $uCount + 1; 
            echo "level $mname<br />"; 
        }

Run anyways, and i dont understand why. I compared the data and both are equal when echo'ed. So using !== should as far as i know only fire if they are not identical. With the current situation i have the update script running 800 times. And with that also literally updating all data in the user table 800 times. While this as far as i know should not be necessary.

Any help would be greatly appreciated.

Anori
  • 73
  • 2
  • 10
  • 1
    While blizzard is not generally seen as 'malicious', you're still trusting them by using their data directly in sql queries; read up about [SQL injection](http://bobby-tables.com) attacks – Marc B Aug 02 '12 at 03:55
  • Are $mlevel and $check['level'] the same type of variable (integer, double, string, etc)? Because !== will return false if they aren't equal in both value and type. So '3' !== 3 is TRUE while '3' != 3 is FALSE because php juggles the types. – Nick Perkins Aug 02 '12 at 03:58
  • Could be that from the side of blizzard all these variables with numbers for rank/level are integers. Since all the stuff put in the database are strings. Though would that really matter if i look at http://php.net/manual/en/language.operators.comparison.php it does state that comparing an integer with a string would convert the string to an integer. – Anori Aug 02 '12 at 04:00
  • what is !== and why are you not using != – 000 Aug 02 '12 at 04:00
  • 5
    must rename my character to "... Drop table ..." http://xkcd.com/327/ –  Aug 02 '12 at 04:01
  • using !== since otherwise it already would break the gender if{. Since the gender if{ uses a 0 in the database. And comparing with an != (not equal to) to 0 never works so decided to compare all with indenticals. Doesnt matter for the outcome here though (except for the gender one of course) – Anori Aug 02 '12 at 04:05
  • var_dump( $mlevel, $check['level'] ); Then, adjust your conditional statement accordingly. – Matthew Blancarte Aug 02 '12 at 04:09
  • @Dagon that's actually a very good idea :) – Vatev Aug 02 '12 at 04:09
  • @MatthewBlancarte Now found what is the problem atleast int(37) NULL the $check['level'] is returning null. – Anori Aug 02 '12 at 04:25
  • Yep, there you go. So you need to go back even further to determine why those values are null. – Matthew Blancarte Aug 02 '12 at 04:27
  • @MatthewBlancarte the weird part about it all is, i can see the values in myAdmin, i can echo them. All of that works. And besides the code there , there isnt much more. Only a page that forms a nice roster of it all and echo's it out in a table format to be viewed for others. – Anori Aug 02 '12 at 04:35
  • @MatthewBlancarte think it might have something to do with this: http://stackoverflow.com/questions/689185/json-decode-returns-null-php another post about how json decode can input Null as value. – Anori Aug 02 '12 at 04:41
  • What do you get when you var_dump( $decode ); What you expect? – Matthew Blancarte Aug 02 '12 at 04:53
  • @MatthewBlancarte Yes all are normal, not one NULL or anything like that. (http://i.imgur.com/70IpD.png) I just tried to simply query the information through a while mysql_fetch_array loop. Just like i do with the table page. And also all those return normal strings when using var_dump. – Anori Aug 02 '12 at 05:07
  • @MatthewBlancarte found a fix (see below) but thank you for the help finding the cause :) – Anori Aug 02 '12 at 05:26

2 Answers2

2

You should try != if($mlevel != $check['level']) as !== checks if they are the same exact value and datatype and since you are retrieving both differently php may have assigned different datatypes to each

Or you can convert both $a =(int)$mlevel and $b = (int)$check['level'] then do a !==

Peter
  • 2,172
  • 1
  • 15
  • 11
  • Tried it still same outcome. It still runs the script 800 times. – Anori Aug 02 '12 at 04:09
  • Tried using `$a =(int)$mlevel; $b = (int)$check['level']; if($a !== $b) { mysql_query("UPDATE user SET level='$mlevel' WHERE charactername='$mname'"); $uCount = $uCount + 1; echo "level $mname
    "; }` like suggested also had no affect.
    – Anori Aug 02 '12 at 04:21
0

While this probably is not the best way to do it, after finding out thanks to @MatthewBlancarte the query got a Null i decided to modify the code:

foreach($decode['members'] as $p) {
$mrank = $p['rank'];
$mname = $p['character']['name'];
$mclass = $p['character']['class'];
$mrace = $p['character']['race'];
$mlevel = $p['character']['level'];
$mgender = $p['character']['gender'];

$check = mysql_query("SELECT * FROM user WHERE charactername='$mname'");


while($row = mysql_fetch_array($check)){
    $prank = $row['rank'];
    $pname = $row['charactername'];
    $pclass = $row['class'];
    $prace = $row['race'];
    $plevel = $row['level'];
    $pgender = $row['gender'];
}

if($check == false)
{ 
    die("Sql query failed"); 
}

if(mysql_num_rows($check) != 0)
{   
    if($mlevel != $plevel)
    {
        mysql_query("UPDATE user SET level='$mlevel' WHERE charactername='$mname'");
        $uCount = $uCount + 1; 
        //echo "level $mname<br />"; 
    }

Adding an extra query while loop with a mysql_fetch_array:

while($row = mysql_fetch_array($check)){
    $prank = $row['rank'];
    $pname = $row['charactername'];
    $pclass = $row['class'];
    $prace = $row['race'];
    $plevel = $row['level'];
    $pgender = $row['gender'];

Is what fixed it, comparing it to those variables works. Thank you all for the help. And before more people comment yes.. i will fix the sql injections.. >.>

Anori
  • 73
  • 2
  • 10