Which loop can best fit in doing the following? - php

I am trying to do a stuff like playing ads based on interest of user. there are certain other parameters set by advertiser. If all those parameters match with a certain user profile then that ad has to be played to him,else check with the next ad..If the list of ad ends and none of them matched then remove one of the parameter and then match. finally if none of the parameters matched then play the ad which is at the top of the list. I have two seperate tables for user and ad, will it be good to join them and fetch data match?
Can anyone tell me which loop will best fit here?
This is what i have tried till now.
`public function adpreferences($ads,$userid){
for($i=0;$i<count($ads);$i++){
$sql="SELECT ua.ads,ua.frm_age,ua.t_age,ua.user_income,ua.user_occupation,ua.user_gender,U.gender,U.income,U.occupation, U.dob FROM user_ad ua LEFT JOIN users U ON U.userid =ua.userid where U.userid='$userid' AND ua.ads='$ads[$i]'";
$res=#mysql_query($sql);
$numOFRows =#mysql_num_rows($res);
if($numOFRows > 0){
while ($result = #mysql_fetch_assoc($res)){
$returnArr[]=$result;
$user_occ=$result['user_occupation'];
$user_incm=$result['user_income'];
$gen=$result['user_gender'];
$f_age=$result['frm_age'];
$t_age=$result['t_age'];
//print_r ($returnArr);
$dob= $result['dob'];
$birthdate = new DateTime($dob);
$today = new DateTime('today');
$age = $birthdate->diff($today)->y;
//print_r ($age);
//return (array($result));
for($i=0;$i<4;$i++){
for($j=0;$j<count($ads);$j++){
if ($ads[$j]!==0){
if(($user_occ==$result['occupation'])&&($user_incm==$result['income'])&&($gen==$result['gender'] || $gen =='Both')&&(($age>= $f_age) && ($age<= $t_age))){
$ads[]=$result['ads'];
}
return $ads[$j];
}
}
for($k=0;$k<count($ads);$k++){
if ($ads[$k]!==0){
if(($user_occ==$result['occupation'])&&($gen==$result['gender'])&&(($age>= $f_age) && ($age<= $t_age))){
$ads[]=$result['ads'];
return $ads[$k];
}
}
}
for($m=0;$m<count($ads);$m++){
if ($ads[$m]!==0){
if(($gen==$result['gender'])&&(($age>= $f_age) && ($age<= $t_age))){
$ads[]=$result['ads'];
return $ads[$m];
}
}
}
for($n=0;$n<count($ads);$n++){
if ($ads[$n]!==0){
if(($gen==$result['gender'])||($gen=='Both'))
{
$ads[]=$result['ads'];
return $ads[$n];
}
}
}
}
return $ads[0];
}
}
}
}``
As suggested i used foreach loop and tried this.
while ($result = #mysql_fetch_array($res)){
$dob= $result['dob'];
$birthdate = new DateTime($dob);
$today = new DateTime('today');
$age = $birthdate->diff($today)->y;
//print_r ($age);
foreach($result as $array){
for($i=0;$i<count($ads);$i++){
if(($array['user_occupation']==$array['occupation'])&& ($array['user_income']==$array['income']) && ($array['user_gender']==$array['fbgender'] || $array['user_gender']=='Both') && (($age>=$array['frm_age'])&&($age<=$array['t_age']))){
return $ads[$i];
break;
}
elseif(($array['user_occupation']==$array['occupation']) && ($array['user_gender']==$array['fbgender'] || $array['user_gender']=='Both') && (($age>=$array['frm_age'])&&($age<=$result['t_age']))){
//return $ads[$i];
break;
}
elseif(($array['user_gender']==$array['fbgender'] || $array['user_gender']=='Both') && (($age>=$array['frm_age'])&&($age<=$array['t_age']))){
//return $ads[$i];
break;
}
elseif(($array['user_gender']==$array['fbgender'] || $array['user_gender']=='Both')){
//return $ads[$i];
break;
}
else{
//return $ads[0];
}
}
}
But i am getting error like undefined variable $array and illegal offset 'user_occupation',illegal offset 'occupation' and so on...

I'd use a foreach() loop with a switch on the arguments, keep track of which ad and how many requirements were fullfilled, once the loop finished, get the best match and show it to the user

You could foreach through the ads and check a condition.
However, if there's a large number of ads you could consider storing them as an array (if not already) to foreach through, or even storing them in a DB (like mysql) and select ONLY the specifc ad needed (would be not doubt faster than foreach if there are a lot of ads to loop through). If mysql returns multiple results, you can fetch the results and loop through with a while loop.

Related

php jumping to previous statement inside a loop

So basically i'm trying to create a complex timetable and i have these two methods that each perform a different check function for me:
Checks if i have a unique array
function tutorAllot($array,$check,$period){
//check for clashes and return non colliding allotment
shuffle($array);
$rKey = array_rand($array);
if(array_key_exists($array[$rKey]['teacher_id'], $check[$period])) {
return $this->tutorAllot($array,$check,$period);
}
return $tutor = array($array[$rKey]['teacher_id'] => $array[$rKey]['subject_code']);
}
checks that each subject does not appear more than twice in a day
function checkDayLimit($data,$check){
//check double day limit
$max = 2;
$value = array_values($check);
$tempCount = array_count_values($data);
return (array_key_exists($value[0], $tempCount) && $tempCount[$value[0]] <= $max) ? true : false;
}
I'm calling the functions from a loop and populating timetable array only if all conditions area satisfied:
$outerClass = array();
foreach ($value as $ky => $val) {
$innerClass = array(); $dayCount = array();
foreach ($periods[0] as $period => $periodData) {
$innerClass[$period] = array();
if(!($periodData == 'break')){
$return = $this->Schedule->tutorAllot($val,$clashCheck,$period);
if($return){
//check that the returned allocation hasnt reached day limit
if($this->Schedule->checkDayLimit($dayCount,$return)){
$innerClass[$period] += $return;
$clashCheck[$period] += $return;
}else{
}
}
}else{
$innerClass[$period] = '';
}
}
//debug($innerClass);
$outerClass[$ky] = $innerClass;
}
My requirements
If the checkDayLimit returns false , i want to go back and call tutorAllot function again to pick a new value.
I need to do this without breaking the loop.
I was thinking maybe i could use goto statement but only when am out of options.
Is there a way i can achieve this without using goto statement.
PHP v5.5.3 Ubuntu
Your architecture seems overly complex. Instead of
pick at random >> check limit >> if at limit, go to re-pick...
Why not incorporate both checks into a single function? It would
Filter out data that is not eligible to be picked, and return an array of legitimate choices
Pick at random from the safe choices and return the pick
addendum 1
I don't think there is any need for recursion. I would use array_filter to pass the data through a function that returns true for eligible members and false for the rest. I would then take the result of array_map and make a random selection from it

Scores per year in array

Pretty new to PHP and i'm trying to achieve something, that in my opinion can be done easily in c#. However in PHP it isn't that easy to achieve for me.
When iterating over an XML file, I want to store all average scores per year.
The years will be unique, the scores should be their values.
Output should be like:
['2012'] => array(8.1, 7.3, 8.8)
['2013'] => array(6.7, 7.7, 5.5)
['2014'] => array(2.3, 7.9, 9.9)
This way I can get all average scores from the year 2014, etc.
In c# I would have created a Dictionary containing a List like:
var yearScores = new Dictionary<string, List<Decimal>>();
My current PHP code looks like:
$yearScores = array(array());
foreach($xml->results->children() as $result) {
//Reset variables
$current_date = null;
$current_average = null;
//Iterate over all 'answer' children in result
foreach($result->children() as $answer) {
//Retrieve Date and Average
if($average[0]['name'] == "date") {
$current_date = date('Y', strtotime($answer));
}
if($average[0]['name'] == "average") {
$current_average = $answer;
}
}
//Validate if we found both current Date and current Average
if(is_null($current_date) || is_null($current_average)) continue;
//The Date and Average exist
//See if the Datum already exists in our array
if(!in_array($current_date, $yearScores)) {
$yearScores[] = $current_date;
}
//The average should be added to the correct year in the array here.
}
How can I add the scores to the correct year arrays in the $yearScores array?
You can do it as follows:
// no need to initialize multidimensional array here
$yearScores = array();
foreach($xml->results->children() as $result) {
foreach($result->children() as $answer) {
//Retrieve Date and Average
// This here does not look right to me
if($average[0]['name'] == "date") {
$current_date = date('Y', strtotime($answer));
}
if($average[0]['name'] == "average") {
$current_average = $answer;
}
if(!isset($yearScores[$current_date])) {
$yearScores[$current_date] = array($current_average);
} else {
array_push($yearScores[$current_date], $current_average);
}
}
}
I am not sure about the ifs however (check my comment). Have you checked if their output is correct?

How to filter foreach array for integers

I have a for-each statement based off a php generated query..
I am trying to figure out how I can make sure all the IDDestinations of the records are the same.
For example in my current query I have 2 records with an IDDestination of 12, one record with an IDDestination of 9 and the last is 3.
I know how to do this in the query but I am trying to generate a message to the user if the IDDestinations are not equivalent.
My code so far.
foreach($results as $row) {
$IDDestination =(int) $row['IDDestination'];
if ($IDDestination == $IDDestination){
echo "<script>alert('All Courses Match Destination.');</script>";
} else {
echo "<script>alert('Courses have different Destinations);</script>";
}
var_dump($IDDestination);
}
This is currently just verifying that each record has an IDDestination Present and tells ME All courses Match.
How can I make it so the INTEGERS are equivalent and give me the same message?
Here's one way; use a variable outside your loop to determine if it's ok or not:
$everything_matches = true;
$id = null;
foreach($results as $row) {
// Set it for the first record.
if($id === null)
$id = $row['IDDestination'];
// If the current iteration's ID matches the first record, $everything_matches
// will stay true, otherwise it's false and we should kill the loop.
if($id != $row['IDDestination']) {
$everything_matches = false;
break;
}
}
// Output your message
$message = $everything_matches ? 'All courses match destination.' : 'Courses have different destinations.';
echo '<script>alert("' . $message . '");</script>';

Return value in foreach loop in CodeIgniter

I am having some trouble in returning values from model to controller Using CodeIgniter. I am passing two arrays from controller to model. I am checking whether both the arrays are not empty and looping them using foreach loop to fetch some values from database and returning the query to controller. Here's my current code
if (!empty($search_for_area) && !empty($search_for_requirement))
{ foreach($search_for_requirement as $search_value_1)
{
foreach($search_for_area as $search_value_2)
{
if($search_value_2 != null && $search_value_1 != null)
{
$nearbytution = $this->db->query('select name,area,contactno from tut_listing where area = "'.$search_value_2.'" and categoryfilter like "%'.$search_value_1.'%" and partner > "" group by name');
print_r($nearbytution->result());
}
}
}
//Line 1
}
print_r($nearbytution->result()); works fine and i am able to view the results. Where should i put return $nearbytution; so that i can get all the fetched values? I tried it in Line 1 but i was getting only values of last array value.
function returnStuff($search_for_area,$search_for_requirement) {
$arr_area = array();
$arr_filter = array();
if ( ! empty($search_for_area) and ! empty($search_for_requirement)) {
foreach($search_for_requirement as $search_value_1) {
foreach($search_for_area as $search_value_2) {
if($search_value_2 != null && $search_value_1 != null) {
$arr_area[] = $this->db->escape($search_value_2);
$arr_filter[] = $this->db->escape_like_str($search_value_1);
}
}
}
}
$str_area = 'NULL';
if ($arr_area)
$str_area = implode(', ', $arr_area);
$str_filter = "'^-$'";
if ($arr_filter)
$str_filter = "'(".implode('|', $arr_filter).")'";
$query = $this->db->query("
SELECT name, area, contactno
FROM tut_listing
WHERE area IN ({$str_area}) AND categoryfilter REGEXP {$str_filter} and partner > '' group by name
");
return $query->result();
}
Seriously, do consider this approach. You only need to bother the poor Mysql server with one call and you get all the data you want at the same time.
Apart from that, practice consistent style in your code. It will save both your time and your hair in the long run.
CodeIgniter escape()
MySQL REGEXP
Try this in the loop:
$nearbytution[] = $this->db->query('select name,area,contactno from tut_listing where area = "'.$search_value_2.'" and categoryfilter like "%'.$search_value_1.'%" and partner > "" group by name')->result();
return $nearbytution;may then be placed at your "Line 1". It will contain an array of query results.
Unless I misunderstand your question why don't you just store all the results in a big array and then return that array?
function returnStuff($search_for_area,$search_for_requirement) {
$data = array();
if (!empty($search_for_area) && !empty($search_for_requirement)) {
foreach($search_for_requirement as $search_value_1) {
foreach($search_for_area as $search_value_2) {
if($search_value_2 != null && $search_value_1 != null) {
$nearbytution = $this->db->query('select name,area,contactno from tut_listing where area = "'.$search_value_2.'" and categoryfilter like "%'.$search_value_1.'%" and partner > "" group by name');
$data[] =$nearbytution->result());
}
}
}
}
return $data;
}
Now $data will be an array of results, each containing the query results. If your result set has to be cleaned up (to remove duplicates for instance) you can just loop through it and do that cleanup.
What you could also maybe do is build a large SQL query in your foreach loops and then just do that one big query and return the results.

as of now it just ignores the if statement and gives them a ticket everytime.php, mysql, If else

Alright so i'm trying to put value in an array and shuffle them to be random, then have it use that random value in a query. I know my code is bad and not to use mysql anymore lets stay off that topic please.
I don't understand why this isn't working I have other things like it that work just fine.
right now it ignores the if statement and gives them a ticket each time.
if(isset($_POST['Submit'])) {
$ticket = array("0","0","0","0","0","0","0","1");
shuffle($ticket);
if ($ticket >= 1) {
echo "You have Found a Shop Ticket!" ;
mysql_query("UPDATE users SET ticket=ticket+1 WHERE username = '".$_SESSION['username']."'")
or die(mysql_error());
} else {
echo "";
}
}
You're checking if the entire array is >= 1, which is obviously TRUE all the time.
Pick a value instead:
$ticket = array_shift($ticket); // do this after you shuffle
try
if (current(shuffle($ticket)) >= 1) {
# yay
} else {
# ney
}
$ticket is an array, not a number.
u could use foreach or array_map to do this.
example:
function foo($n){
if($n >= 1){//do something}
}
$ticket = array("0","0","0","0","0","0","0","1");
shuffle($ticket);
array_map('foo', $ticket);

Categories