Forum Moderators: coopster

Message Too Old, No Replies

Help creating tag system in PHP

Comma Delimited PHP tags

         

zerodesigns

3:42 am on Jun 18, 2009 (gmt 0)

10+ Year Member



Hi All,
I'm trying to create a tag feature, and I'm having some trouble implementing it.

What I have is a database with the columns id, name, email, tags, etc. In the "tags" column (which may or may not be empty), the tags are entered as comma separated values like so: tag1, tag2, tag3,

I need to be able to select all the tags from the database (WHERE tags != ""), and then do an explode of some sort to separate all the tags using the commas. Also, if there are two or more identical tags in different rows, I need it to only show each unique tag once.

Any help would be greatly appreciated. Thanks guys.

Tommybs

7:33 am on Jun 18, 2009 (gmt 0)

10+ Year Member



I've often thought about tags and how best to implement them and I wonder if you are better off creating a new table that holds purely tags (i.e a tag_id and the tag itself). You could then have another table that manages the tags and your data.

e.g. article_tag(article_id, tag_id)

You can then just use inner joins to select the tag, the number of times it's id occurs and a particular article, this should help you with the unique problem as the tag is only ever stored once regardless of how many things it is associated with.

zerodesigns

3:30 pm on Jun 18, 2009 (gmt 0)

10+ Year Member



I thought about that and think that could work too, but my database already had tags built into the same table as the rest of the client information. I've come up with a solution that doesn't yet resolve the unique problem, but solves the rest of it.

$query = "SELECT tags FROM table";
$result = mysql_query ($query);

$tags = array();
while($row = mysql_fetch_assoc($result)) {
if ($row['tags'] != '') {
array_push($tags, $row['tags']);
}
}

$foo = implode(",", $tags);
$tags = explode(',', $foo);

$tagData = '';
foreach ($tags AS $tags)
{
$tagData .= "<a href=\"/search.php?tag=$tags\">$tags</a>, ";
}
echo substr_replace($tagData, '', -2);

Basically it goes through and adds new tags into the "$tags" array where the field is not null. Then, I implode the array into a single variable, and then explode the variable using the comma as the delimiter.

The substr_replace() is to remove trailing commas from the final results.

zerodesigns

3:45 pm on Jun 18, 2009 (gmt 0)

10+ Year Member



I'll post the unique tag solution once I've completed it.

zerodesigns

5:07 pm on Jun 18, 2009 (gmt 0)

10+ Year Member



Still having problems with the unique tag filter.

I've been trying to use array_unique($tags), but it only seems to filter some tags and not others.

Any suggestions on how to do this within the code posted in comment #3?

Thanks.

henry0

5:19 pm on Jun 18, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



zerodesigns, welcome to WebmasterWorld!

Here is model you may look at
sorry, I won't have time to support it
but you will get the idea

// enter tags in db
// hereI require at least two tags per entry

$tags=trim($_POST["tags"]); //echo"tttt $tags<P>";

if (empty($tags))
{
echo"<b>The tag field is empty<br>Please etc.....";
exit();
}

////// check if at least 2 words are in array

$tg=explode(",", $tags);
$num_tag=count($tg);
if(($num_tag <2))
{
echo"You entered $num_tag tag number, you need entering 2 words minimum
etc.....";
exit();
}

////// end check array word num
$str=$tags;
$str=strlen($tags); //echo"strlen $str<P>";
if($str>100)
{
echo"<b>The submited total tag combo is longer than 100 characters and space<br>Please etc......";
exit();
}

if (!preg_match("/^[a-z-0-9\,\ ]+$/",$str) )
{
echo"<b>The submited tag should only contain alphanumerical lower case characters and commas!<br>
Please <etc...";
exit();
}

// select tags from DB ////////////////////////////////////

SELECT
tags
FROM
#*$!#*$!xx
WHERE
zzzzz='$zzzzzz'
");
if (!$result)
{
echo "DB Error, could not list sections\n";
echo 'MySQL Error: ' . mysql_error();
exit;
}

while ($row=$db->fetch_array($result_tags) )
{
$tags=$row['tags'];

$tags=unserialize($tags); // print_r($tags);
$tags=array($tags);
$tags=array_merge(array_unique($tags)); //

foreach($tags as $key=>$tags)
{
echo"<a href='your main page.php?rrrrrrrt=$rrrrrr&tags=$tags' target='iframe'>Click the tags to read the tags related whatever => $tags</a><br>&nbsp;<br>";
}

}
echo"<iframe name='iframe' width='980' height='200' scrolling='yes'>";

zerodesigns

5:45 pm on Jun 18, 2009 (gmt 0)

10+ Year Member



Hi Henry0, Thanks for the response.
That seems to be a completely new tag solution though, and I'm 90% done with my existing system that works within my existing database.

Basically the rows in the database could have the following tags (duplicates are intentional):
row1: tag1, tag2, tag2, tag3
row2: tag4
row3: tag5, tag6, tag3

I use the following code to loop through the array and add all the tags in the database to the $tags array.


$tags = array();
while($row = mysql_fetch_assoc($result)) {
if ($row['tags'] != '') {
array_push($tags, $row['tags']);
}
}

I then implode the $tags array to get all the values into one variable like so:


$foo = implode(",", $tags);

Then I explode the consolidated array to create a new array with the tags separated by commas.


$tags = explode(',', $foo);

Then, I loop through my new $tags array and echo out the individual tags like so:


$tagData = '';
foreach ($tags AS $tags)
{
$tagData .= "<a href=\"/search.php?tag=$tags\">$tags</a>, ";
}
echo substr_replace($tagData, '', -2);

The substr_replace() part is just to get rid of trailing commas, but it may be what's causing the problem, I don't know.

What I need to do, is find a way to remove duplicate entries from the $tags array before I echo the tags out. I've tried $tags = array_unique($tags), to try to consolidate it, and it worked but only for certain tags. Other tags would still continue to display even if they were duplicates.

Any help you could offer would be greatly appreciated. Thanks.

henry0

7:32 pm on Jun 18, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Did you play with
<<<<
$tags=array($tags);
$tags=array_merge(array_unique($tags));
>>>>

zerodesigns

8:17 pm on Jun 18, 2009 (gmt 0)

10+ Year Member



I did, and that has the same results of simply using $tags=array_unique($tags);

It does cut out some duplicate tags, like if I have two rows in the database that only have one tag each, and each tag is identical, array_unique() will filter out the second identical tags. But that's not always the case, and if I have two rows with tags like so:

row1: tag1, tag2, tag3
row2: tag4, tag1, tag5

It often won't detect and filer out the two identical tags. It also won't detect and filter out the tags if they are both originally in the same row like this:

row1: tag1, tag1, tag2

I'm not sure what the cause of that could be. I'm using the array_unique() function after I've already exploded the data into an array where each tag is an independent entry in the array.

Tommybs

9:18 pm on Jun 18, 2009 (gmt 0)

10+ Year Member



Is there any white space that could make them non-unique? have you tried things like trim or strtolower on the tags to make them all lowercase for comparison?

zerodesigns

2:57 am on Jun 20, 2009 (gmt 0)

10+ Year Member



Thanks Tommybs,
The solution ended up being ltrim(), as there was some whitespace at the beginning of the very first tag in each row.

Problem solved, thanks for your help guys.

keith1764

2:44 am on Sep 4, 2009 (gmt 0)

10+ Year Member



I was having the same problem and google brought me here. This solution has worked mostly, but I can't figure out where you put the ltrim() statement.

Thanks.

Tommybs

8:18 am on Sep 4, 2009 (gmt 0)

10+ Year Member



put it before the tag string and existing tags so that you can compare them

keith1764

11:30 pm on Sep 4, 2009 (gmt 0)

10+ Year Member



"put it before the tag string and existing tags..." - That makes no sense to me.

"...so that you can compare them" - Who's comparing anything? I'm not comparing. Are you comparing?

Anyway, I found my own solution after a few hours and half a pack of cigs (I'm new to PHP. I know the solution was probably simple to most of you, but lay off ;-) ).

For the next googler who comes after me, here's what I did after the implode and explode:

foreach ($tags as $tag)
{
$tag = ltrim($tag);
array_push($tags_final, $tag);
}

$tags = array_unique($tags_final);

Hope that helps. It might not be the most logical or efficient solution, but it works (Maybe this could have been done in the while loop, but I couldn't figure out how).

And seriously people, if you're going to respond to a message, make sure your response makes sense and assume the person who will be reading it doesn't know what you know.

BTW, kudos to ZeroDesigns. During my search I found a lot of long, drawn out, convoluted solutions to this problem. His was simple and straight-forward. Thanks buddy.

Tommybs

9:04 am on Sep 5, 2009 (gmt 0)

10+ Year Member



I happened to be at work and just posted a quick reply. Sorry if it was short but trying to help others isn't my day job. I wasn't assuming anything, I just thought I'd try and post something that might help you on your way no matter how brief. Considering you'd got most of the solution like you said earlier how was I meant to know what level of PHP you were at. Oh and to clarify the 'compare' part was about comparing any new tags with existing ones so that you might just increment a count instead of storing the same tag twice somewhere.

This forum is all about helping each other and there is a good atmosphere here. I guess I might just go back to being a lurker, at least that way no one has a pop at you for not leaving replies

zerodesigns

4:30 pm on Sep 5, 2009 (gmt 0)

10+ Year Member



Alright guys let's be cool here.

keith1764:
I'm glad you found the solution, and I hope it serves you well.

Tommybs:
Thanks for your help with the initial solution. Your counsel was invaluable and I hope you continue to respond to people's requests and needs on this website.