To preface this, I know cron-expression library exists. But I only need this one tiny bit for a quick display in a table in PHP. Also the library needs php 7.1 and I have to implement this on a php 5.3 site that doesn't really have composer set up.
So given this cron schedule
00 00 02,06,10,14,18,22 * * *
How do I calculate the next run date based on the current date?
I found another answer here on SO and it was working until it encountered the multiple explicit hours.
function calculate_next_cronjob($cronjob, $elementpositions)
{
$wildcard = false;
$elements = preg_split('/[^\d*]+/', $cronjob);
foreach (preg_split('/[^a-z]+/i', $elementpositions) as $key => $element) {
$value[$element] = $elements[$key];
switch ($element) {
case 's':
if ($value[$element] == '*') {
$value[$element] = date('s') + 1;
$wildcard = true;
}
break;
case 'i':
if ($value[$element] == '*') {
$value[$element] = date('i') + ($wildcard === true ? 0 : 1);
$wildcard = true;
}
break;
case 'H':
if ($value[$element] == '*') {
$value[$element] = date('H') + ($wildcard === true ? 0 : 1);
$wildcard = true;
}
break;
case 'd':
if ($value[$element] == '*') {
$value[$element] = date('d') + ($wildcard === true ? 0 : 1);
$wildcard = true;
}
if (intval($value[$element]) == 0) {
$value[$element] = 1;
}
break;
case 'm':
if ($value[$element] == '*') {
$value[$element] = date('m') + ($wildcard === true ? 0 : 1);
$wildcard = true;
}
if (intval($value[$element]) == 0) {
$value[$element] = 1;
}
break;
default:
unset($value[$element]);
}
}
$cy = date('Y');
$ny = $cy + 1;
if (time() < mktime($value['H'], $value['i'], $value['s'], $value['m'], $value['d'], $cy)) {
$value['Y'] = $cy;
} else {
$value['Y'] = $ny;
}
return date('Y-m-d H:i', mktime($value['H'], $value['i'], $value['s'], $value['m'], $value['d'], $value['Y']));
}
I imagine this function can be modified to account for this. I need help making those modifications.
Thank you
Related
I want to transform query string like pending, shipped or cancel to number status.
$q = strtolower($keyword);
if($q == 'pen' or $q == 'pend' or $q == 'pending' ) {
$d = 1;
} elseif($q == 'shi' or $q == 'ship' or $q == 'shipped') {
$d = 2;
} elseif($q == 'can' or $q == 'cancel' ) {
$d = 3;
} else {
$d = 4;
}
$query->whereStatus($d);
Current query working fine but too much or. It's possible to do in shorten way?
str_is(query, stringToSearch) will probably be enough:
if (str_is('pen*', $q)) {
$d = 1;
}
Else you could parse them from arrays:
$pendingArray = ['pen', 'pend', 'pending'];
if (in_array($q, $pendingArray)) {
$d = 1;
}
If these are all the conditions you need, you could always use a switch.
$q = strtolower($keyword);
$d = 4;
switch($q) {
case 'pen':
case 'pend':
case 'pending':
case 'pen':
$d = 1;
break;
case 'shi':
case 'ship':
case 'shipped':
$d = 2;
break;
case 'can':
case 'cancel':
$d = 3;
break;
}
$query->whereStatus($d);
If this needs to be called on a model, it could be saved to a Laravel scope function like so:
on Laravel model
public function scopeSearchStatus($query, $keyword) {
/** All the code above **/
}
Then it can be called cleanly anywhere you'd like:
SomeModel::searchStatus($keyword);
You could also try this:
<?php
$q = strtolower($keyword);
$d = (preg_match('/\b(pen|pend|pending)\b/', $q)) ? 1 : 4;
$d = (preg_match('/\b(shi|ship|shipped)\b/', $q)) ? 2 : 4;
$d = (preg_match('/\b(can|cancel|)\b/', $q)) ? 3 : 4;
$query->whereStatus($d);
I was wondering if there is an elegant solution to this programming problem.
There is a date of an event that meets the following conditions:
1) it can be 'from' - 'to'
2) OR it can be 'from'
AND (repeating at defined intervals n times OR indefinitely).
The interwals can be day/week/month or year
There is a participant on that event. (S)He may have a period/date attached, when (s)he is unavailable.
1) the date can be 'from' - 'to'
2) the date can be only 'from'
3) the date can be only 'to'
I need to check if participant's 'unavailable' date - if present - overlaps in any way with event date.
For now it's a hotchpotch or conditions. Code's not finished, I'll have to add more. Language - PHP. I'm usding DateTime PHP object for comparing dates.
Can this be improved somehow or conditions are the only way to go in this case? I don't need an exact code, just an idea.
if($event->recurring === '0') {
// Non recurring event
if($eventEndValid && $userFromValid && $userToValid) { $user->available = ($userFrom < $eventStart && $userTo < $eventStart) || ($userFrom >= $eventEnd && $userTo > $eventEnd); }
else if($userFromValid && $userToValid) { $user->available = ($userFrom < $eventStart) && ($userTo <= $eventStart); }
else if(!$eventEndValid && !$userToValid) { $user->available = false; }
else if(!$eventEndValid && !$userFromValid) { $user->available = $userTo <= $eventStart; }
else if($eventEndValid && !$userToValid) { $user->available = $userFrom >= $eventEnd; }
else if($eventEndValid && !$userFromValid) { $user->available = $userTo <= $eventStart; }
} else {
$dIntStr = 'P';
switch($event->recurring_frequency) {
case '1':
$dIntStr .= '1D';
break;
case '2':
$dIntStr .= '1W';
break;
case '3':
$dIntStr .= '1M';
break;
case '4':
$dIntStr .= '1Y';
break;
}
// Case 1
if(!$userToValid) { $user->available = false; }
if((!$userFromValid && $userToValid)) { $user->available = $userTo <= $eventStart; }
// Case 2 - number of intervals is unlimited
if($event->recurring_frequency === '0') {
if($userToValid && $userTo <= $eventStart) { $user->available = true; }
else if($userTo > $eventStart) {
// If unavailability is between the intervals then true
$user->available = true;
}
else { $user->available = false; }
}
// Case 2 - number of intervals is limited
$dateInterval = DateInterval($dIntStr);
if($event->recurring_frequency === '0') {
}
}
You usually can use functions to shorten the code. However i'd think a class is more suitable for this:
class DateRange{
public $from, $to;
public function inBetween($outer){
return $this->from >= $outer->from && $this->to <= $outer->to;
}
function __construct($from, $to){
if($a = $from->getTimestamp() == $b = $to->getTimestamp()){
throw new \Exception('A period cannot be the same time');
} else {
if($a < $b){
$this->from = $a;
$this->to = $b;
} else {
$this->from = $b;
$this->to = $a;
}
}
}
}
$today = new Datetime();
$lastyear = (new Datetime())->modify('-1 year');
$from = (new Datetime())->modify('-9 month');
$outer = new DateRange($lastyear, $today);
$inner = new DateRange($from, $today);
if($inner->inBetween($outer)){
echo 'it is';
} else {
echo 'it isnt';
}
You can add more methods like inBetween() as you see fit this way.
I know so long time has passed, but:
/**
* isInDateRange PHP>=5.3,7,8.0
*
* #param DateTime $startRange
* #param DateTime $endRange
* #param DateTime $dateTarget
* #return bool
*/
function isInDatesRange( DateTime $startRange, DateTime $endRange, DateTime $dateTarget) {
//->some dates range validations if you want to...
if($endRange == $dateTarget) return true;
$interval = new DateInterval('P1D');
$range = new DatePeriod($startRange, $interval, $endRange);
foreach($range as $day ) {
if($day->format('Y-m-d') == $dateTarget->format('Y-m-d')) return true;
}
return false;
}
/**
* isInDateRange PHP>8.2.0
*
* #param DateTime $startRange
* #param DateTime $endRange
* #param DateTime $dateTarget
* #return bool
*/
function isInDatesRange( DateTime $startRange, DateTime $endRange, DateTime $dateTarget) : bool {
//->some dates range validations if you want to...
$interval = new DateInterval('P1D');
$range = new DatePeriod($startRange, $interval, $endRange, DatePeriod::INCLUDE_END_DATE);
foreach($range as $day ) {
if($day->format('Y-m-d') == $dateTarget->format('Y-m-d')) return true;
}
return false;
}
I wrote a class for badge activation and it should be refactored now.
Are there any good advices, how should I refactor it's trigger() method?
The source of the class is in github:
https://github.com/heal25/ced/blob/master/models/BadgeActivator.php
The problematic method:
public function trigger($id, $data = []) {
if (!$this->_uid) $this->setUid(Yii::app()->player->model->uid); //set default uid
$activate = false;
switch ($id) {
//case 'login_1': $activate = true; break;
case 'max_nrg_35': if ($data['energy_max'] >= 35) $activate = true; break;
case 'max_nrg_100': if ($data['energy_max'] >= 100) $activate = true; break;
case 'skill_35': if ($data['skill'] >= 35) $activate = true; break;
case 'skill_100': if ($data['skill'] >= 100) $activate = true; break;
case 'strength_35': if ($data['strength'] >= 35) $activate = true; break;
case 'strength_100': if ($data['strength'] >= 100) $activate = true; break;
case 'energy_drink': $activate = true; break;
case 'level_10': if ($data['level'] >= 10) $activate = true; break;
case 'level_100': if ($data['level'] >= 100) $activate = true; break;
case 'dollar_50': if ($data['dollar'] >= 50) $activate = true; break;
case 'dollar_5000': if ($data['dollar'] >= 5000) $activate = true; break;
case 'travel_loc3': if ($data['water_id'] == 3) $activate = true; break;
case 'travel_county2': if ($data['county_id'] == 2) $activate = true; break;
case 'travel_county9': if ($data['county_id'] == 9) $activate = true; break;
case 'routine_100': if ($data['routine'] >= 100) $activate = true; break;
case 'loc_routine_4b': if ($data['water_id']==4 and $data['routine'] > 0) $activate = true; break;
case 'loc_routine_13s': if ($data['water_id']==13 and $data['routine'] >= 3) $activate = true; break;
case 'loc_routine_28s': if ($data['water_id']==28 and $data['routine'] >= 3) $activate = true; break;
case 'loc_routine_37g': if ($data['water_id']==37 and $data['routine'] >= 9) $activate = true; break;
case 'loc_routine_52b': if ($data['water_id']==52 and $data['routine'] > 0) $activate = true; break;
case 'loc_routine_61s': if ($data['water_id']==61 and $data['routine'] >= 3) $activate = true; break;
case 'loc_routine_71g': if ($data['water_id']==71 and $data['routine'] >= 9) $activate = true; break;
case 'loc_routine_72e': if ($data['water_id']==72 and $data['routine'] >= 27) $activate = true; break;
case 'loc_routine_46d': if ($data['water_id']==46 and $data['routine'] >= 81) $activate = true; break;
case 'setpart_3': if ($data['cnt'] >= 3) $activate = true; break;
case 'setpart_10': if ($data['cnt'] >= 10) $activate = true; break;
case 'setpart_30': if ($data['cnt'] >= 30) $activate = true; break;
case 'first_duel_win': if ($data['role'] == 'caller' and $data['winner'] == 'caller') $activate = true; break;
case 'duel_success_100': if ($data['cnt'] >= 100) $activate = true; break;
case 'duel_fail_100': if ($data['cnt'] >= 100) $activate = true; break;
case 'duel_rate_40': if ($this->getSuccessRate(100, $data) <= 40) $activate = true; break;
case 'duel_rate_25': if ($this->getSuccessRate(300, $data) <= 25) $activate = true; break;
case 'duel_rate_10': if ($this->getSuccessRate(600, $data) <= 10) $activate = true; break;
case 'duel_rate_60': if ($this->getSuccessRate(100, $data) >= 60) $activate = true; break;
case 'duel_rate_75': if ($this->getSuccessRate(300, $data) >= 75) $activate = true; break;
case 'duel_rate_90': if ($this->getSuccessRate(900, $data) >= 90) $activate = true; break;
case 'duel_money_100': if ($data['dollar'] >= 100) $activate = true; break;
case 'duel_money_1000': if ($data['dollar'] >= 1000) $activate = true; break;
case 'duel_win_chance35': if ($data['winner'] and $data['chance'] <= 35) $activate = true; break;
case 'duel_win_chance20': if ($data['winner'] and $data['chance'] <= 20) $activate = true; break;
case 'duel_win_chance5': if ($data['winner'] and $data['chance'] <= 5) $activate = true; break;
case 'duel_lose_chance65': if (!$data['winner'] and $data['chance'] >= 65) $activate = true; break;
case 'duel_lose_chance80': if (!$data['winner'] and $data['chance'] >= 80) $activate = true; break;
case 'duel_lose_chance95': if (!$data['winner'] and $data['chance'] >= 95) $activate = true; break;
case 'duel_2h': if ($data['role'] == 'caller' and date('G')==2) $activate = true; break;
case 'shop_item10': if (Yii::app()->player->model->owned_items >= 10) $activate = true; break;
case 'shop_bait20': if (Yii::app()->player->model->owned_baits >= 20) $activate = true; break;
case 'set_b': if ($data['id']==1) $activate = true; break;
case 'set_s': if ($data['id']==2) $activate = true; break;
case 'set_g': if ($data['id']==3) $activate = true; break;
case 'set_sell_b': if ($data['id']==1) $activate = true; break;
case 'set_sell_s': if ($data['id']==2) $activate = true; break;
case 'set_sell_g': if ($data['id']==3) $activate = true; break;
case 'club_join': $activate = true; break;
case 'club_create': $activate = true; break;
case 'club_members_8': if ($data['cnt'] >= 8) $activate = true; break;
case 'login_days_7': if ($this->getLoginDays() >= 7) $activate = true; break;
case 'login_days_30': if ($this->getLoginDays() >= 30) $activate = true; break;
case 'login_days_60': if ($this->getLoginDays() >= 60) $activate = true; break;
case 'win_contest': $activate = true; break;
}
if ($activate) {
return $this->activate($id);
}
return false;
}
I can extract the activations for 'loc_routine_*' cases, but it isn't much.
I'm not familiar with Yii, but from glancing over their docs, you could probably refactor the trigger method to make use of Yii Validators and the DI container. Something along these lines:
class BadgeActivator
…
public function trigger($id, array $data)
{
$badgeValidator = $this->badgeValidators->findById($id);
if ($badgeValidator->validate($data)) {
$this->activate($id);
}
}
}
The BadgeValidators object is a simple collection of objects implementing the BadgeValidator interface. You need to inject this to your BadgeActivator.
class BadgeValidators
{
private $validators = [];
public function __construct(array $badgeValidators)
{
foreach ($badgeValidators as $badgeValidator) {
$this->addBadgeValidator($badgeValidator);
}
}
public function addBadgeValidator(BadgeValidator $badgeValidator)
{
$this->validators[$badgeValidator->getId()] = $badgeValidator;
}
public function findById($badgeId)
{
if (isset($this->validators[$badgeId])) {
return $this->validators[$badgeId];
}
throw new BadgeValidatorNotFoundException(
"No BadgeValidator found for badge id [$badgeId]"
);
}
}
The BadgeValidator interface is the contract all concrete validators need to obey. Their purpose is to map from $data to Yii's build in validators or to encapsulate additional/unique validation logic.:
interface BadgeValidator
{
public function getId();
public function validate($value = null);
}
A concrete Validator would then look like this:
class MaxEnergy35 implements BadgeValidator
{
public function getId()
{
return 'max_nrg_35';
}
public function validate($value = null)
{
$validator = new yii\validators\IntegerValidator();
$validator->min = 35;
return $validator->validate($value['max_energy']);
}
}
You could move the configuration for this class to the DI config as well, e.g. you could inject maxEnergy, validatorId and the Yii Validator. If you do that, you'll only have one class MaxEnergy instead of MaxEnergy35 and MaxEnergy100. For sake of simplicity, I'll keep it this way now.
Here is one with custom logic:
class DuelRate40 implements BadgeValidator
{
public function getId()
{
return 'duel_rate_40';
}
public function validate()
{
return $this->getSuccessRate(100, $data) <= 40;
}
private function getSuccessRate($limit, array $data)
{
// moved from BadgeActivator
}
}
As you can see, it's trivial to make your BadgeValidators with custom logic and without using the Yii validators. In this particular case, I just moved the getSuccessRate rate method to the validator. You could easily see that it's misplaced on the BadgeActivator because it didn't have any cohesion to any class properties. Obviously, if you need this code in multiple validations, you could make it configurable again, so you have only one validator of that kind, instead of duplicating that method in each concrete one.
Now, for each case in your switch/case, simply add another concrete BadgeValidator and inject it to the BadgeValidators in the DIConfig.
In your ced/config/main.php:
// more config …
components => [
'badgeValidator' => [
'class'=> 'application.components.BadgeValidator',
'badgeValidators' => [
['class'=>'MaxEnergy35'],
['class'=>'MaxEnergy100'],
['class'=>'DuelRate40'],
// more validators …
]
],
// other components …
]
Note: I have no clue if this is the correct way to use Yii's DI config. I am just assuming from your file on GitHub. But I guess, you'll know how to change it if necessary.
And whenever you need to add a new Badge, you simply write the Validator and wire it up in the config. You will never need to touch the BadgeActivator again. This will also significantly lower the Cyclomatic Complexity of the BadgeActivator. And it's trivial to add Unit Tests for each of the components above.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have noticed similar repetition and trying to work around using a single for loop for this if I can to minimize the code length:
I wouldn't need to use a switch case if I can form a loop instead?
$returnNo variable starts at 5, each case multiplied by 2 then minus 1.
where it shows "$a<=", it starts at 5 and each case multiplied by 2 then plus 3.
the if() statement starting at if($matchno == 7), each case multiplied by 2 then plus 1.
the final if() statement starting at if($matchno == 8), each case multiplied by 2.
I have done up to case 64, it will actually go up to 512. As I know the code is repeating I am hoping someone can help me produce a single loop for this?
Many thanks!
switch($max) {
case 80 :
$returnNO = 5;
for($a = 1; $a<=5; $a++) {
if($matchno == $a || $matchno == ($a+1)){
$matchinfo['matchno'] = $returnNO;
$matchinfo['place'] = ($matchno == $a ? 'clan1' : 'clan2');
return $matchinfo;
}
$returnNO++;
$a++;
}
if($matchno == 7){
$matchinfo['winner'] = true;
return $matchinfo;
}elseif($matchno == 8){
$matchinfo['third_winner'] = true;
return $matchinfo;
}
break;
case 160 :
$returnNO = 9;
for($a = 1; $a<=13; $a++) {
if($matchno == $a || $matchno == ($a+1)){
$matchinfo['matchno'] = $returnNO;
$matchinfo['place'] = ($matchno == $a ? 'clan1' : 'clan2');
return $matchinfo;
}
$returnNO++;
$a++;
}
if($matchno == 15){
$matchinfo['winner'] = true;
return $matchinfo;
}elseif($matchno == 16){
$matchinfo['third_winner'] = true;
return $matchinfo;
}
break;
case 320 :
$returnNO = 17;
for($a = 1; $a<=29; $a++) {
if($matchno == $a || $matchno == ($a+1)){
$matchinfo['matchno'] = $returnNO;
$matchinfo['place'] = ($matchno == $a ? 'clan1' : 'clan2');
return $matchinfo;
}
$returnNO++;
$a++;
}
if($matchno == 31){
$matchinfo['winner'] = true;
return $matchinfo;
} elseif($matchno == 32){
$matchinfo['third_winner'] = true;
return $matchinfo;
}
break;
case 640 :
$returnNO = 33;
for($a = 1; $a<=61; $a++) {
if($matchno == $a || $matchno == ($a+1)){
$matchinfo['matchno'] = $returnNO;
$matchinfo['place'] = ($matchno == $a ? 'clan1' : 'clan2');
return $matchinfo;
}
$returnNO++;
$a++;
}
if($matchno == 63){
$matchinfo['winner'] = true;
return $matchinfo;
}elseif($matchno == 64){
$matchinfo['third_winner'] = true;
return $matchinfo;
}
break;
}
}
I'll use the first two cases as an example:
switch ($max) {
case 80:
$returnNO = 5;
$loopCount = 5;
$winner = 7;
$thirdWinner = 8;
break;
case 160:
$returnNO = 9;
$loopCount = 13;
$winner = 15;
$thirdWinner = 16;
break;
...
}
for ($a = 1; $a <= $loopCount; $a++) {
if ($matchno == $a || $matchno == ($a + 1)) {
$matchinfo['matchno'] = $returnNO;
$matchinfo['place'] = ($matchno == $a ? 'clan1' : 'clan2');
return $matchinfo;
}
}
if ($matchno == $winner) {
$matchinfo['winner'] = true;
return $matchinfo;
} else if ($matchno == $thirdWinner) {
$matchinfo['third_winner'] = true;
return $matchinfo;
}
Simply explained, remove the code that repeats all the time and try to parameterize it (either by creating a function or by putting all repeated code somewhere else... in this example, I put the repeating code after the switch statement and paremeterized it.
If I understood well, here is an alternative solution which I think would work for all cases you specified, with no use of switch case.
$div10 = $max / 10;
$maxLoop = $div10 - 3;
$returnNO = $div10 / 2 + 1;
for($a = 1; $a<=$maxLoop; $a++) {
if($matchno == $a || $matchno == ($a+1)){
$matchinfo['matchno'] = $returnNO;
$matchinfo['place'] = ($matchno == $a ? 'clan1' : 'clan2');
return $matchinfo;
}
$returnNO++;
$a++;
}
if($matchno == ($div10-1)){
$matchinfo['winner'] = true;
return $matchinfo;
}elseif($matchno == $div10){
$matchinfo['third_winner'] = true;
return $matchinfo;
}
I am having a small problem with my PHP MySQL Select. The function is inside of a PHP class. Here is the error I get:
Warning: mysql_fetch_array() expects parameter 1 to be resource,
integer given in C:\xampp\htdocs\include\database.php on line 59
Warning: extract() expects parameter 1 to be array, null given in
C:\xampp\htdocs\include\database.php on line 59
The function just simply updates the database to show what browser and OS they visited the site with. The function is called from another file that is called by an AJAX call that uses POST to send the data about the OS and browser that was gathered from a Javascript file. It only fails if there is an entry of the IP address already in the database. If there is no IP Address entry in the database it succeeds in creating one.
Here is my code:
function addStat($browser, $os){
$IE = 0; $Firefox = 0; $Safari = 0; $Opera = 0; $Chrome = 0; $otherb = 0;
$Windows = 0; $Linux = 0; $Mac = 0; $Android = 0; $iOS = 0; $otheros = 0;
$ql = 0; $totalVisits = 0;
$ip = ip2long($_SERVER['REMOTE_ADDR']);
$q1 = mysql_query("SELECT * FROM " . DB_STATS . " WHERE ip='$ip'", $this->connection);
if (mysql_num_rows($q1)==0){
$browser = mysql_real_escape_string($browser);
$os = mysql_real_escape_string($os);
switch($browser){
case "Internet Explorer":
$IE += 1;
break;
case "Firefox":
$Firefox += 1;
break;
case "Safari":
$Safari += 1;
break;
case "Opera":
$Opera += 1;
break;
case "Chrome":
$Chrome += 1;
break;
default:
$otherb += 1;
break;
}
switch($os){
case "Windows":
$Windows += 1;
break;
case "Mac OS X":
$Mac += 1;
break;
case "Linux":
$Linux += 1;
break;
case "Android":
$Android += 1;
break;
case "iOS":
$iOS += 1;
break;
default:
$otheros += 1;
break;
}
$q = $this->query("INSERT INTO " . DB_STATS . " VALUES (null, '$ip', '$Chrome', '$IE', '$Firefox', '$Opera', '$Safari', '$otherb', '$Windows', '$Mac', '$Linux', '$Android' , '$iOS' , '$otheros', 1)");
if ($q == true){
return(1);
}
else{
return(0);
}
}
else if (mysql_num_rows($q1)==1){
extract(mysql_fetch_array($ql));
switch($browser){
case "Internet Explorer":
$IE += 1;
break;
case "Firefox":
$Firefox += 1;
break;
case "Safari":
$Safari += 1;
break;
case "Opera":
$Opera += 1;
break;
case "Chrome":
$Chrome += 1;
break;
default:
$otherb += 1;
break;
}
switch($os){
case "Windows":
$Windows += 1;
break;
case "Mac OS X":
$Mac += 1;
break;
case "Linux":
$Linux += 1;
break;
case "Android":
$Android += 1;
break;
case "iOS":
$iOS += 1;
break;
default:
$otheros += 1;
break;
}
$totalVisits += 1;
$q = $this->query("UPDATE " . DB_STATS . " set Chrome='$Chrome', IE='$IE', Firefox='$Firefox', Opera='$Opera', Safari='$Safari', otherb='$otherb', Windows='$Windows', Mac='$Mac', Linux='$Linux', Android='$Android' , iOS='$iOS' , otheros='$otheros', totalVisits='$totalVisits'");
if ($q == true){
return(1);
}
else{
return(0);
}
}
else{
return(-1);
}
}
I hope everything made sense and that someone will help.
I see it now -- you used $ql (lower case L) when you intend to use $q1. Let this be a lesson against using very short variable names or very similar names.
// $ql was initialized to 0
$ql = 0; $totalVisits = 0;
// $q1 holds the result resource
extract(mysql_fetch_array($q1));
It is not advisable to call extract() on the output of mysql_fetch_array() unless you also specify the second parameter MYSQL_ASSOC as the fetch type. By default it returns both numeric and associative indices for each column.
extract(mysql_fetch_array($q1, MYSQL_ASSOC));
// Or better
extract(mysql_fetch_assoc($q1));
In general, I would probably advise against using extract() in most any situation, since it results in numerous variables dumped into the global namespace, in particular when you have done SELECT * without being specific about which columns are selected. Better to access them via their array:
$row = mysql_fetch_assoc($q1);
echo $row['browser'];