views:

149

answers:

5

User writes a series of tags (, separated) and posts the form.
I build an array containing the tags and delete dupes with array_unique() php function.

I'm thinking of doing:

  • go through the array with foreach($newarray as $item) { ... }
  • check each $item for existence in the tags mySQL table
  • if item does not exists, insert into tags table

Is there a FASTER or MORE OPTIMUM way for doing this?

+2  A: 

You can call implode( ',' $array ) then use the IN SQL construct to check if there are existing rows in the db.

Example:

<?php
   $arr = ...
   $sql = 'SELECT COUNT(*) FROM table WHERE field IN ( ' . implode( ',', $arr ) . ' );';
   $result = $db->query( $sql );
?>
Jacob Relkin
I think you meant to say `implode(',', $array)`. You would use `explode()` to turn a string into an array.
awgy
You also defined `$arr` and then used `$array`.
Jack M.
@awgy, @Jack thanks
Jacob Relkin
Also, please note a potential security concern here. The strings in `$arr` are never escaped. This can be corrected with: `$arr = array_map('mysql_real_escape_string', $arr, array($mySqlConn));` (where `$mySqlConn` is the resource returned by `mysql_connect()`)
awgy
+1  A: 
$tags = array('foo', 'bar');

// Escape each tag string
$tags = array_map('mysql_real_escape_string', $tags, array($sqlCon));

$tagList = '"' . implode('", "', $tags) . '"';

$qs = 'SELECT id FROM tag_list WHERE tag_name IN (' . $tagList . ')';
awgy
If you’re so cautious about SQL injections then you shouldn’t forget the quotes around them.
Gumbo
So true-- that's what I get for rushing a response. :)
awgy
A: 

I don´t know if it's faster, but you can use mysql's IN. I guess you'd have to try.

jeroen
A: 

You could build up a big query and do it in one shot, instead of many little queries:

SELECT DISTINCT tag
  FROM my_tags
 WHERE tag in ( INPUT_TAGS )

Just build up INPUT_TAGS as a comma-separated list, and make sure you properly escape each element to prevent SQL injection attacks.

Justin Ethier
+3  A: 

I'm hoping that people can comment on this method. Intuition tells me its probably not the best way to go about things, but what do you all think?

Instead of making an extra call to the DB to find duplicates, just add a unique constraint in the DB so that tags cannot be inserted twice. Then use INSERT IGNORE... when you add new tags. This method will ignore the errors caused by duplications while at the same time inserting the new items.

thetaiko
+1 This is exactly what I'd do. Unless you specifically need to handle the tags with some logic when duplicates are there, I would `INSERT IGNORE` and forget about it. Why bother with a separate `SELECT` and loop just to remove duplicate data from an `INSERT`, when `INSERT IGNORE` does it for you?
zombat
I would think this would work well, especially since it would make the duplicate-finding `SELECT` superfluous. It may be worthwhile, though, to benchmark the two approaches just to be sure.
awgy
@thetaiko. My tags table has:- id: primary, autoinc- title: varchar(50)How should I add the duplicates contraint?
Enrique
@Enrique - `ALTER TABLE \`tags\` ADD UNIQUE \`unique_title\` (\`title\`);`
thetaiko
@thetaiko Awesome! I got wrong and added an index index instead unique. Thanks for your help!
Enrique