Forum Moderators: coopster

Message Too Old, No Replies

check for a string in an array

         

smallcompany

8:08 am on Nov 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I have this code:

$v2 = "variable";
$v2 = strtolower($v2);
$lines = file("log.txt");
$fp = fopen("log.txt", "a");
if(in_array($v2,$lines))
{
fclose($fp);
} else {
fwrite($fp, "$v2\n");
fclose($fp);
}
/*
print "<pre>";
print_r($lines);
print "</pre>";
*/

The purpose of this is to write the variable into a flat text file only if it does not exist. If it's already there, it should ignore it.

For IF statement, if I do it manually in a form of:

if (($v2 == "") ¦¦
($v2 == "variable1") ¦¦
($v2 == "variable2") ¦¦
($v2 == "variable3"))

it works like a charm.

But, if I read my file into an array where each line is an entry, it always writes, regardless if the variable is already there or not.

On a side, I found somewhere that in_array is slow, and that isset works much better. I also found that there are other ways of checking for values within the array.

I wonder which one you prefer in such cases, when you work with flat files, text only.

Thanks

omoutop

8:22 am on Nov 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



quick observation
You create your array ($lines = file("log.txt");)
before you perform any checks for your text.

This casues a logical error at the end of script
/*
print "<pre>";
print_r($lines);
print "</pre>";
*/

This will not show your new text (if it is imported to your text file), since $lines is unaffected by your if statememnt.

Try to set the $lines = file("log.txt");, after the IF
and check again

dreamcatcher

8:29 am on Nov 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Don`t forget that with 'file', you have a new line character present after each entry. As your comparison isn`t working, this is probably the issue?

Try trimming the array before using in_array:

$lines = array_map('trim',file("log.txt"));

Now your comparison should work as expected.

dc

caribguy

8:36 am on Nov 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Rewrite to

$v2 = "variable";
$v2 = strtolower($v2);
$lines = file("log.txt");
if(in_array($v2,$lines))
{
$fp = fopen("log.txt", "a");
fwrite($fp, "$v2\n");
fclose($fp);
}

and rtfm at [php.net...]

Anyango

9:42 am on Nov 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



When DC speaks, Listen! ;)

That 1 line of code he wrote, solves your problem.

smallcompany

5:56 pm on Nov 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



When DC speaks, Listen!

I did! And it worked! I thank you very much.

In regards of my other question, would you be fine with array_in or would rather replace it by something else that does the same job, but faster? The flat file should not be bigger than thousand lines, plus I can always empty it.

My goal is to slow the whole process the least I can.

Thanks

rtfm

I did lose my eyes around array related stuff. About "file" function I was just too happy to find that by simply reading the whole file creates an array. I found that on a site other than php.net

Thanks for the ping anyway, it does not hurt to hear it from time to time. We should read the manuals more than we do. ;)

caribguy

6:18 pm on Nov 26, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Didn't mean it to sound harsh :)

As a non-php programmer, three things caught my eye. Opening the file before you needed to, the redundancy you built in with if..then..else, and manually adding '\n'

That's why I went straight for the docs and found:

Note: Each line in the resulting array will include the line ending, unless FILE_IGNORE_NEW_LINES is used, so you still need to use rtrim() if you do not want the line ending present.

smallcompany

12:18 am on Nov 27, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



As a non-php programmer, three things caught my eye. Opening the file before you needed to, the redundancy you built in with if..then..else, and manually adding '\n'

Man, what would be if you're php programmer? I wish I'm non-programmer like you. :)

Your suggestion failed if there was no log.txt file. Not a big deal as I can create it initially and leave it there.

What I was doing with my way was to create it if it was not there. That way I can cut/paste and let go further, starting from zero (again).

But, the trade could be expensive (open the file every time), so I agree with your view and will work on the simplification of this process. Thanks for making a point.

Still, I have a question about that in_array vs. other functions. What to use and when?

Thanks

Anyango

4:12 am on Nov 27, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




The flat file should not be bigger than thousand lines, plus I can always empty it.

Then Grab all the file contents in one string and look for "$v2\n" in that string. That will make it just 1 comparison rather than PHP needing to search the whole array.
Not sure if that would be better but sounds like it atleast ;)

[edited by: Anyango at 4:13 am (utc) on Nov. 27, 2008]

SarK0Y

6:56 pm on Nov 28, 2008 (gmt 0)

10+ Year Member



Hi, smallcompany.
>>>Still, I have a question about that in_array vs. other functions. What to use and when?
you can make binary tree and speed will be more or use mysql table with type 'Heap'. second variant is more soft to realize.

[edited by: SarK0Y at 6:57 pm (utc) on Nov. 28, 2008]

vincevincevince

8:21 am on Nov 29, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I wonder which one you prefer in such cases, when you work with flat files, text only.

$r=shell_exec("/usr/bin/grep -m 1 $search_pattern $file_name");

In my experience, that is by far the fastest way to find whether $search_pattern (check pattern syntax in your UNIX manual) is within $file_name...