...

View Full Version : array/update while/foreach trouble



fuzzy1
03-29-2007, 05:58 AM
It's been a LONG day and I'm getting punchy, but I keep running up against variations on the following select_query/array foreach/update_query scenario, and it just gives me fits every time. I always muddle through, but it's been eating up my days. I really need to get a handle on it.

Having trouble updating from the $matches[] array here...

// If we have no results, die
if ($numrows != 0)
{
while ($row = mysql_fetch_assoc($result))
{
$description= $row['description'];
$_get_email_addr = preg_match_all("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i", $description, $matches);
$email_addr = $matches[0];

$_update_invalid = "UPDATE contacts SET invalid_email ='1'
WHERE email1 ='$email_addr[?]' ";// here's where I'm stuck
$query = @mysql_query ($_update_invalid) or die ("Query Failed Updating Invalid emails." .mysql_error()); // Run the query.
$affected_rows = mysql_affected_rows();
}
echo $affected_rows .'<br>';
echo $numrows;
} One of these days I'm going to get a handle on arrays and the foreach and while loops:mad: Meanwhile, more than eager for any insights.

iLLin
03-29-2007, 02:59 PM
Your searching your description for email addresses? Then updating email1 by what you find? Doesn't seem like that would work as intended. Unless I am missing something? Why not just run a validate function on your email1 field and if valid, do nothing, if not valid update and set to invalid?

And I didnt see a foreach and the only array I saw was from preg_match_all |(besides your db rows)?

fuzzy1
03-30-2007, 04:41 AM
Thanks iLLin,
As I said, it was late, and I was very tired. The point was not to check the validity of the email addresses syntactically, but to indicate in the related contacts table that the email address of record for a particularl contact is NO LONGER valid. The description field mentioned, is the body text of a bounced email (returned undeliverable for whatever reason) indicating a problem with the send_to_address of a given sent email. While we have other means in place to track said invalid email back to the contact record of origin, these means are not infallible (what is?) and don't cover ALL the bases (what does?) Anyway, the script in question merely plugs a hole.

I'm certain that only recently I've managed to constuct a VERY similar script without the addition/use of a foreach loop. Exactly how or why eludes me, as does the reason I have yet to get the knack for this type of construct despite having constrcted a good dozen of them in the last month or so.
Anyway, did need the foreach this time around. Solution as follows. Any and all critique welcome as I really am trying to get a handle on this. Thanks.
/////////////////////////////////////////////////////////////////////////////////////////////
// Check for Bounced with NO IDENTIFIER TAG in the email //////////////////////////////////////////////
///////////////////////////////tj added 03/29/07///////////////////////////////////////////
$bounce_no_removeme = "SELECT * FROM emails
WHERE intent = 'bounce'
AND name LIKE '%fail%'
AND description LIKE '%Delivery to the following recipients failed.%'
AND description NOT LIKE '%removeme.php%'
AND date_entered > date_sub(curdate(), interval 2 day)
";
$result = @mysql_query ($bounce_no_removeme)or die ("Query failed - Bounced_no_removeme " .mysql_error());
$numresults=mysql_query($bounce_no_removeme);
$numrows=mysql_num_rows($numresults);
if ($numrows != 0)
{
while ($row = mysql_fetch_assoc($result))
{
$description= $row['description'];
$_get_email_addr = preg_match_all("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i", $description, $matches);
$invalid_addr = $matches[0];
foreach ($invalid_addr as $invalid){
$_update_invalid = "UPDATE contacts SET invalid_email ='1' WHERE email1='$invalid' AND invalid_email !='1' ";
$query = @mysql_query ($_update_invalid) or die ("Query Failed Updating Invalid emails." .mysql_error());
}
}
}

iLLin
03-30-2007, 05:04 AM
Ok I understand now, looks good except your running the same query twice?

$result / $numresults...

aedrin
03-30-2007, 07:13 PM
AND name LIKE '%fail%'
AND description LIKE '%Delivery to the following recipients failed.%'
AND description NOT LIKE '%removeme.php%'


If you can find a better solution for these, I'd suggest using them.

fuzzy1
04-06-2007, 05:09 PM
Okay... here we are again.

First off, thanks to iLLin for the feed back on

$numresults=mysql_query($bounce_no_removeme);
$numrows=mysql_num_rows($numresults);
I've been doing this wrong for months. My take is that it should be... simply
$numrows=mysql_num_rows($result);
which seems to work fine? Meanwhile, I'm back at another such script as described above, and I'm really sick of NOT GETTING IT!!!!
$sql = "SELECT * FROM catalog ";
$result = mysql_query($sql);
$numrows=mysql_num_rows($result);
if ($numrows != 0)
{
while ($row = mysql_fetch_assoc($result))
{
$key =$row['id'];
$cost =$row['Cost'];
$_Cost = preg_split ("/[\$,]+/", $cost);
$_price=(($_Cost[1]*.40)+$_Cost[1]);
$price = "$".number_format ($_price, 2);
$new_price[] ="'$price'";
}
foreach( $new_price as $key => $value)
{
//echo $value ."<br>";

$update_pricing ="UPDATE catalog SET Price = '$value' WHERE id ='$key' ";
$query=@mysql_query($update_pricing) or die ("Update Failed " .mysql_error());
}
}
Now, I have already twisted this one seven ways from Sunday, to the point where what is posted here probably make no sense to anyone NOT LEAST OF ALL TO ME, but... I consistently struggle with getting the array into a foreach type update query.

Echoing $value from a foreach where the array is defined LIKE

$new_price[] ="'$key', '$price'"; I get a list of the values desired (id, and corresponding Price) but getting those values into the UPDATE QUERY continues to elude me. At best, I usually end up updating the first record only.

If anyone knows of a good example/set of examples on this type of select_query/array foreach/update_query scenario, I would be ever so grateful to learn of it.

fuzzy1
04-06-2007, 05:20 PM
Aha!!
The preceeding/following is one of those examples where the foreach is NOT NECESSARY, but I don't understand why. Anyone? Please.
$sql = "SELECT * FROM backup_catalog WHERE product NOT LIKE 'Wallaby%' ";
$result = mysql_query($sql);
$numrows=mysql_num_rows($result);
if ($numrows != 0)
{
while ($row = mysql_fetch_assoc($result))
{
$key =$row['id'];
$cost =$row['Cost'];
$_Cost = preg_split ("/[\$,]+/", $cost);
$_price=(($_Cost[1]*.40)+$_Cost[1]);
$price = "$".number_format ($_price, 2);

$update_pricing ="UPDATE backup_catalog SET Price = '$price' WHERE id ='$key' ";
$query=@mysql_query($update_pricing) or die ("Update Failed " .mysql_error());
}
}

aedrin
04-06-2007, 05:35 PM
$price = "$".number_format ($_price, 2);

Storing a price as a "string" is a horrible idea. I'd suggest storing it as a number.

The foreach is not necessary because there is no reason to save up all the changes. What it did before:

- Go through each price, change the price, and store it in an array
- Go through price in array, update database with each new price

While the second one only does this:

- Go through each price, change the price, and store it in the database

You can see the second one is a little bit more efficient. Although PHP is good enough with arrays that it won't make much of a difference.

The broken part in the preceding was this:



$new_price[] ="'$price'";


Which should've been:



$new_price[$key] ="'$price'";


And what is with this?


$_price=(($_Cost[1]*.40)+$_Cost[1]);

Why not


$_price=$_Cost[1] * 1.40;

The naming convention is that only private variables are preceeded by an underscore.

Making your code readable makes it easier to catch mistakes. Try to avoid overusing parenthesis and complicated calculations. It only makes it harder to debug.

Your code is right in theory. Just needs some finetuning. ;)

fuzzy1
04-06-2007, 06:03 PM
Many Thanks aedrin,:thumbsup:

First off,
Storing a price as a "string" is a horrible idea.
Why exactly? Seems to be working just fine as is (Not being flippant here, just... well... curoius??? )

Secondly,
clearly my grasp of arrays is weak at best. Could you point me to a good discussion/examples of your use of
$new_price[$key] ="'$price'"; I think I see it but... would like to read up a little with specific/related examplels.

Thirdly,
On "Why not"
$_price=$_Cost[1] * 1.40; well... duhhh? I guess that's what I get for working past my bedtime? Math much????:eek:

P.S. Might I infer that the foreach from my first example could have been skipped???

aedrin
04-06-2007, 06:24 PM
Yes, the foreach was without a purpose. :)


Why exactly? Seems to be working just fine as is (Not being flippant here, just... well... curoius??? )

1. As you can see from your code, you have to extract the data, parse it and then store it again. Were it stored as a number, it would've taken 1 query:


UPDATE products SET price = price * 1.4

2. You can easily change the format as long as you pass all your output uses 1 generic function.



function formatPrice($price) {
return '$' . number_format($price, 2);
}

while ($row = mysql_fetch_assoc($result)) {
echo formatPrice($row['price']);
}


You'd put the formatPrice function in an include file, obviously. ;)


clearly my grasp of arrays is weak at best. Could you point me to a good discussion/examples of your use of

Practice your use of arrays. They're one of PHP's strong sides. They're easy to use and can be used for almost anything.

The difference between these two statements:



$array = array();
$array[] = $value;
$array[$key] = $value;


Is that the first one will auto generate an index. This is always a numeric index. The second one actually stores whatever was in the $key variable and uses it as the index.

So when you use foreach as such:



foreach ($array as $key => $value) {
// do some things
}


For the second element you put in there, you will know that $key and $value will be the same as what you stored.

But for the first element, you will have no idea what $key as. As it was auto generated. It would in this case be 0. But if the array was prefilled, who knows what would end up in there?

As always, the best source of information is PHP's own website.

http://us.php.net/manual/en/ref.array.php

Spend some time reading up on what is in there. Don't forget to examine the user submitted notes, as they usually contain valuable hints and tips.

fuzzy1
04-06-2007, 09:53 PM
Very Nice! Thank You!

I have learned and partially digested so much in the past few months, it's daunting to consider all I've yet to learn!

A SINGLE QUERY???? Geezz .... processing... processing... (as a whisp of smoke beigns rolling from my ears).

Seriously though, Thanks for taking the time.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum