homepage Welcome to WebmasterWorld Guest from 23.22.173.58
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
Getting info from string
Marked

5+ Year Member



 
Msg#: 4076208 posted 9:54 am on Feb 8, 2010 (gmt 0)

Hi all,

I am trying to write something that displays the most voted on choice from a poll.

In the database, all the choices, options etc. for the poll are stored in a single string.. so im not sure how i can get the info I want, but im sure there are some php functions which can do the trick.

Here's an example of one:
a:1:{i:1;a:3:{s:8:"question";s:27:"Will you switch
over to
VX?";s:6:"choice";a:3:{i:1;s:3:"Yes";i:2;s:2:"No";
i:3;s:17:"I'll use
both";}s:5:"votes";a:3:{i:1;i:5;i:2;i:7;i:3;i:12;}
}}

What I need to do with this string is get the 'choice'(as a string, e.g.: 'Yes','No','I
ll use) that has the highest number of votes.

In the above the string, here are choices: votes :
Yes : 5
No : 7
I'll use both : 12

So basically what I'm looking to do is return 'I'll use both' from the string, because it has he most votes.

Thanks in advance.

 

CyBerAliEn

5+ Year Member



 
Msg#: 4076208 posted 9:00 pm on Feb 8, 2010 (gmt 0)
Your situation is unusual. Given the use of the database, I'm surprised your polling isn't setup in a more friendly manner.

So, assuming an example string is in this form:
a:1:{i:1;a:3:{s:8:"question";s:27:"Will you switch over to VX?";s:6:"choice";a:3:i:1;s:3:"Yes";i:2;s:2:"No"; i:3;s:17:"I'll use both";}s:5:"votes";a:3:{i:1;i:5;i:2;i:7;i:3;i:12;}}}

What makes this "difficult" is that your results are stored in a proprietary, unusual string format. I suppose someone who is really good with regular expressions could tackle this, but that is one of my weak points, lol. So here is how I would go about doing it.... I would create a few functions to help me "process" this.

(suppose that a record is stored as variable "record"). I found this so odd/unusual I actually spent the time to write something up to process it (lol). Below is the code I wrote for a function poll_arrayize(). Its input is a string in the format noted above. Its output is an associative array.

*******************************************************
function poll_arrayize($str)
{
$output = array();
$i = 0;
$mode = 'start';
$parts = explode(';',$str);
if (count($parts)>0)
{
//Run thru "parts"
foreach ($parts as $part)
{
//Process Question/Choices
if (strpos($part,'"')===false) { /*do-nothing;skip-part*/ }
else
{
$quoted = explode('"',$part);
$thisString = $quoted[1];
if ($mode=='start') { if ($thisString=='question') { $mode = 'question'; } }
else if ($mode=='question')
{
if ($thisString=='choice') { $mode = 'choice'; }
else { $output['question'] = $thisString; }
}
else if ($mode=='choice')
{
if ($thisString=='votes') { $mode = 'votes'; }
else { $output['choices'][] = $thisString; }
}
}
//Break Off Loop (if voting)
if ($mode=='votes') { break; }
$i ++;
}
//Run Processing for Votes
if ($mode=='votes')
{
//Setup Votes Info
$offset = ($i+1);
$length = ((count($output['choices']))*2);
$votes = array_slice($parts,$offset,$length);
//Get Vote Counts
$voteCounts = array();
$vc = 0;
if (count($votes)>0)
{
foreach ($votes as $vc=>$voteInfo)
{
if ($vc%2)
{
list($junk,$voteNum) = explode(':',$voteInfo);
$voteCounts[] = $voteNum;
}
$vc++;
}
$output['votes'] = $voteCounts;
}
}
}
//Function Output
return $output;
}
*******************************************************

Note: This forum is messing with the code above I think, so I told it to disable the forum codes. Let me know if it works out. The above function looks uglier without the tabs. This is a "custom" solution. It is tested and verified to work (with your example string/record), but no guarantees are given. Could it be written better? Perhaps... but it will take your 'custom string' and turn it into a friendly PHP array.

If you pass your example "record" into this function, it will output an array in the form (straight from PHP given your record):

Array
(
[question] => Will you switch over to VX?
[choices] => Array
(
[0] => Yes
[1] => No
[2] => I'll use both
)

[votes] => Array
(
[0] => 5
[1] => 7
[2] => 12
)

)

So... given that you query your DB for the records, you can now quickly "process" them for what you want by calling this function on the string. From this resulting array, you can quickly get: (a) the question; (b) the choices; and (c) the votes. The array index for 'choices' and 'votes' should match.

IE: If you know you have choice #2 (value='No' and index='1'). You can get the number of votes by accessing the array as: $array['votes'][1]

Best of luck!

[1][[b]edited by[/b]: CyBerAliEn at 9:46 pm (utc) on Feb 8, 2010][/1]

CyBerAliEn

5+ Year Member



 
Msg#: 4076208 posted 9:04 pm on Feb 8, 2010 (gmt 0)

Hmm... I just re-read your post, and you want a way to retrieve the item with the most votes!

Well, you can easily make a new "wrapper" function that utilizes the above function. Such as this:

function poll_getWinner($array)
{
//This function requires that the 'array' input be in the form provided by poll_arrayize()
$output = array();
$votes = $array['votes'];
$max = max($votes);
$maxKey = array_search($max,$votes);
$output['count'] = $max;
$output['choice'] = $array['choices'][$maxKey];
$output['choiceIndex'] = $maxKey;
//Function Output
return $output;
}


This function requires that the "record array" (produced by poll_arrayize function) be fed into it. This function will then return an associative array in the form:

Array
(
[count] => 12
[choice] => I'll use both
[choiceIndex] => 2
)



So, all in all... here is how you can make it all work out:

<?php
$record = "a:1:{i:1;a:3:{s:8:\"question\";s:27:\"Will you switch over to VX?\";s:6:\"choice\";a:3:i:1;s:3:\"Yes\";i:2;s:2:\"No\"; i:3;s:17:\"I'll use both\";}s:5:\"votes\";a:3:{i:1;i:5;i:2;i:7;i:3;i:12;}}}";
$recordArray = poll_arrayize($record);
$winner = poll_getWinner($recordArray);
echo "<p>The winner of the poll <b>{$recordArray['question']} is &quot;{$winner['choice']}&quot; with a total vote of <b>{$winner['count']}</b>.</b></p>";
?>


Since the functions turn the string into a useful array, you can manipulate it a lot easier to fit your needs.

bedlam

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4076208 posted 10:11 pm on Feb 8, 2010 (gmt 0)

I hate to tell you this after all the work you put in CyBerAliEn, but that looks like an ordinary serialized [php.net] array to me (though as-is, it can't be unserialized...probably what's pasted in the first post is not precisely what's returned by the query...)

This means you can get the un-serialized array back by running the query result through php's unserialize() function [php.net]. After that, it'll be possible to just access the data in the array normally.

Based on a very quick look, it looks like you'll need to find the key of the item in the 'votes' array with the largest value and return the value corresponding to the same key in the 'choice' array.

-- b

CyBerAliEn

5+ Year Member



 
Msg#: 4076208 posted 11:04 pm on Feb 8, 2010 (gmt 0)

grrr... lol

I recognized an underlying "order" but didn't recognize it as a serialized array. Oh well... looks like I re-created the serialization lol

Marked

5+ Year Member



 
Msg#: 4076208 posted 3:26 am on Feb 9, 2010 (gmt 0)

CyBerAliEn, thank you for all your hard work and the effort you put into your post. I really do appreciate the time you spent trying to help me.

I am really pleased that I got this to work, bedlam was correct and the unserialize function gave me the array to work with. Although I needed an extra function in there.

Here's what I used:
function max_key($array) {
foreach ($array as $key => $val) {
if ($val == max($array)) {
return $key;
}
}
}
$winner_id = max_key($poll_data[1]['votes']);
$poll_winner = $poll_data[1]['choice'][$winner_id];

This is actually going to be a module on the homepage which automatically displays the winner of a member of the month contest we have on the forums. When the topic with the poll is closed, the code we have discussed here will be run and the winners username will show up. Now what I'm going to do is query the members table for the username that matches the winner from the poll(the choice) so the winner members avatar will displayed as well as a link to their profile.

Thanks again for the help guys. I am really happy I got this working.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved