dubbelj
dubbelj

Reputation: 1160

PHP, foreach weird behaviour

Sorry for the limited title. Go easy on me, i'm not quite advanced at PHP.

In my functions.php i've got the following 2 functions to see if the "recievers" or "senders" already exist.

function getSenderId($fromAddress){
    global $database;
    $check = $database->query("SELECT * FROM custMod_senders WHERE email = '$fromAddress'");
    if($check->fetchRow() > 0){
        $id = $check->fetchRow();
        return $id['id'];       
    }else{
        return 0;
    }
}

function getReceiverId($toAddress){
    global $database;
    $check = $database->query("SELECT * FROM custMod_receivers WHERE email = '$toAddress'");
    if($check->fetchRow() > 0){
        $id = $check->fetchRow();
        return $id['id'];       
    }else{
        return 0;
    }
}

Now in my the script i've got the following.

$from = $_SESSION['fromAddress'];
$to = $_SESSION['addresses'];
$std = $_SESSION['possibleStd'];

    if (!is_array($to)){
        $to = array($to);       
    }



foreach($to as &$address) { 

        if(getReceiverID($address) == 0){
            echo 'receiver not found';
            $database->query("INSERT INTO custMod_receivers (email, possibleStd) VALUES ('$address', '$std')");

        }

        if(getSenderID($from) == 0){
            echo 'sender not found';
            $database->query("INSERT INTO custMod_senders (email) VALUES ('$from')");

        }

        $send_id = getSenderID($from);
        $receive_id = getReceiverID($address);

        $database->query("INSERT INTO custMod_lt_send_rec (send_id, receive_id) VALUES ('$send_id', '$receive_id')");

    };  

Given that my vars, session and tablenames all exist and are available.. What is wrong with this loop or function setup?

The problem is in de last query within the foreach(). the link table is giving all kinds of crazy results.

EDIT: The problem is that the results in the DB are double, incomplete or missing. As if my 2 functions are giving false results...

Upvotes: 1

Views: 150

Answers (3)

cbrandolino
cbrandolino

Reputation: 5883

One thing that surely looks weird is, you're adding the $address to the database when there's no address, and the $from where there is no from.

Your structure in verbose pseudocode, to help you understand:

if there is no receiver                                1
   then put the receiver intoto the database           2
if there is no sender                                  3
   then put the sender into the database               4
anyway                                                 5
   put both in the database                            6

So if one of the elements is present, it duplicates it in the db (line 6); if none is set, it puts empty strings in the db - since the command in line 6 gets executed anyway

That does not look like something you might want to do, amirite?

So, here is how that series of conditional clauses should be - if I got you:

if ((getSenderID($from)) and (getReceiverID($address)) {
   //code to put both into the db
}
elseif ((getSenderID($from)) {
   //code to put the sender only
}
else {
   //code to put the receiver only
}

Also, you might want to take a look at some php manual for conditional statements.

Upvotes: 0

Dejan Marjanović
Dejan Marjanović

Reputation: 19380

;

At the end is not needed. Exatly what values are messed up?

EDIT:

This should lower the number of unnecessary queries, if from is not an array.

$send_id = getSenderID($from);
if(getSenderID($from) == 0){
    echo 'sender not found';
    $database->query("INSERT INTO custMod_senders (email) VALUES ('$from')");
    $send_id = $from;
}

foreach($to as $address){  
    $receive_id = getReceiverID($address);
    if($receive_id == 0){
        echo 'receiver not found';
        $database->query("INSERT INTO custMod_receivers (email, possibleStd) VALUES ('$address', '$std')");
        $receive_id = $address;
    }

    $database->query("INSERT INTO custMod_lt_send_rec (send_id, receive_id) VALUES ('$send_id', '$receive_id')");
}

Upvotes: 0

mattbasta
mattbasta

Reputation: 13709

If you're using mysqli (which you should), your database object can automatically grab the IDs. It's faster (two fewer lookups) and instantaneous.

$conn = new mysqli("localhost", "username", "password");
$conn->query("INSERT BLAH BLAH BLAH");

$id_of_new_row = $conn->insert_id;

What you're likely seeing (as you mentioned in the comments) is that the database is still writing and you're seeing a cached response (null) or some other improper value due to concurrency nonsense. It makes no sense to send an extra two queries when you can just grab the IDs that you're looking up with the two functions you posted, though, so switch your DB object over to this method and let us know how it goes!

Upvotes: 1

Related Questions