How can this big method be refactored? - php

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.

Related

PHP, switch case returned undefined variable

Hy,
I got switch case inside function when but when i call it, i got error Undefined Variable and i don't know why (i use PHP 8)
private function getIDFromBrand() {
switch ($this->brand) {
case "Niky":
$id = 1;
break;
case "Pumo":
$id = 4;
break;
case "Coke":
if ($this->typecoke== 0) {
$id = 2;
} else {
if ($this->typecoke== 1) {
$id = 3;
}
}
break;
case "Tomato":
$id = 5;
break;
case "Riles":
$id = 6;
break;
case "TEST":
$id = 7;
break;
}
return $id; // Error Undefined variable $id
}
When i declare $id at the top of my function, like
$id = null
or
$id = 0
The switch doesn't update it, so it will return null or 0, it will return the declared value.
Your switch statement has no default branch, so if $this->brand is, say, "Stack Overflow", it will not run any of the statements, and $id will never be set.
See the PHP manual for the switch statement:
A special case is the default case. This case matches anything that wasn't matched by the other cases.
Similarly, if $this->brand is "Coke", but $this->typecoke is, say, 42, it will not match either of the conditions in that branch.
switch ($this->brand) {
case "Niky":
$id = 1;
break;
case "Pumo":
$id = 4;
break;
case "Coke":
if ($this->typecoke== 0) {
$id = 2;
} elseif ($this->typecoke== 1) {
$id = 3;
} else {
$id = -1; // WAS PREVIOUSLY NOT SET
}
break;
case "Tomato":
$id = 5;
break;
case "Riles":
$id = 6;
break;
case "TEST":
$id = 7;
break;
default:
$id = -1; // WAS PREVIOUSLY NOT SET
break;
}

Calculate next cron run date in PHP

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

How to implement variable with value operator statement in IF statement?

How to implement variable with value operator statement in IF statement ?
if ($dcustomer['mix_max']=='MIN') {
$operator=">=";
} elseif ($dcustomer['mix_max']=='MAX') {
$operator="<=";
}
if ($djml['Tamount'] ."$operator". $dcustomer['limit_maksimal']){
}
<?php
$dcustomer = array("mix_max"=>"MIN","limit_maksimal"=>2);
$djml = array("Tamount"=>"");
if ($dcustomer['mix_max']=='MIN') {
$operator=">=";
} elseif ($dcustomer['mix_max']=='MAX') {
$operator="<=";
}
echo $djml['Tamount'] .$operator. $dcustomer['limit_maksimal'];
You cannot (well, you could if you used eval(), which should be avoided for obvious reasons).
But the same effect can be achieved with a multiplier:
switch ($dcustomer['mix_max']) {
case 'MIN':
$multiplier = 1;
break;
case 'MAX':
$multiplier = -1;
break;
default:
// Always prepare for the unknown :-)
throw new \Exception("Unknown operator");
}
if ($djml['Tamount']*$multiplier >= $dcustomer['limit_maksimal']*$multiplier) {
...
}
But I think it would be clearer and more flexible:
$condition = null;
switch ($dcustomer['mix_max']) {
case 'MIN':
$condition = ($djml['Tamount'] >= $dcustomer['limit_maksimal']);
break;
case 'MAX':
$condition = ($djml['Tamount'] <= $dcustomer['limit_maksimal']);
break;
default:
// Always prepare for the unknown :-)
throw new \Exception("Unknown operator");
}
if ($condition) {
...
}

Phalcon BeforeSave not receiving data before saving?

Before I save my model, I would like to check if $ CONT_CEDULA meets the requirements. If not, then don't save. But when saving, it is as if the variable $ CONT_CEDULA hasn't got any data. I want to know if I'm doing well or need some other event or function. Also, the echo outputs no data.
beforeSave method
public function beforeSave() {
echo $this->$CONT_CEDULA;
switch (strlen($this->$CONT_CEDULA)) {
case 10:
return validarCI($this->$CONT_CEDULA);
break;
case 13:
return validarRUC($this->$CONT_CEDULA);
break;
default:
echo "Numero de caracteres invalidos" ;
return FALSE;
}
SpmContacto model
<?php
class SpmContacto extends \Phalcon\Mvc\Model {
public $CONT_CODIGO;
public $CONT_CEDULA;
public $CONT_RUCIDE;
public $CONT_NOMBRE;
public $CON_ESTADO;
public $CONT_TELEFO;
public $CONT_DIRECC;
public $CONT_AREA;
public $CONT_CARGO;
public $CONT_TIPOXX;
public $CONT_EMAIL;
public $CONT_USUARIO;
public $CONT_CLAVE;
public $CONT_CLAVEE;
public $CONT_FECNACI;
public $CONT_FECINSC;
public $CONT_TIPOCODIGO;
/**
* Initialize method for model.
*/
public function initialize() {
$this->setSchema("SPOLS");
$this->hasMany('CONT_CODIGO', 'SPMREFERENCIA', 'CONT_CODIGO', array('alias' => 'SPMREFERENCIA'));
$this->hasMany('CONT_CODIGO', 'SPTDETALLE', 'CONT_CODIGO', array('alias' => 'SPTDETALLE'));
$this->hasMany('CONT_CODIGO', 'SPTENCABEZADO', 'CONT_CODIGO', array('alias' => 'SPTENCABEZADO'));
}
function validarCI($strCedula) {
$suma = 0;
$strOriginal = $strCedula;
$intProvincia = substr($strCedula, 0, 2);
$intTercero = $strCedula[2];
$intUltimo = $strCedula[9];
if (!settype($strCedula, "float"))
return FALSE;
if ((int) $intProvincia < 1 || (int) $intProvincia > 23)
return FALSE;
if ((int) $intTercero == 7 || (int) $intTercero == 8)
return FALSE;
for ($indice = 0; $indice < 9; $indice++) {
//echo $strOriginal[$indice],'</br>';
switch ($indice) {
case 0:
case 2:
case 4:
case 6:
case 8:
$arrProducto[$indice] = $strOriginal[$indice] * 2;
if ($arrProducto[$indice] >= 10)
$arrProducto[$indice] -= 9;
//echo $arrProducto[$indice],'</br>';
break;
case 1:
case 3:
case 5:
case 7:
$arrProducto[$indice] = $strOriginal[$indice] * 1;
if ($arrProducto[$indice] >= 10)
$arrProducto[$indice] -= 9;
//echo $arrProducto[$indice],'</br>';
break;
}
}
foreach ($arrProducto as $indice => $producto)
$suma += $producto;
$residuo = $suma % 10;
$intVerificador = $residuo == 0 ? 0 : 10 - $residuo;
return ($intVerificador == $intUltimo ? TRUE : FALSE);
}
function validarRUC($strRUC) {
if (strlen($strRUC) != 13)
return FALSE;
$suma = 0;
$strOriginal = $strRUC;
$intProvincia = substr($strRUC, 0, 2);
$intTercero = $strRUC[2];
if (!settype($strRUC, "float"))
return FALSE;
if ((int) $intProvincia < 1 || (int) $intProvincia > 23)
return FALSE;
if ((int) $intTercero != 6 && (int) $intTercero != 9) {
if (substr($strRUC, 10, 3) == '001')
return validarCI(substr($strRUC, 0, 10));
return FALSE;
}
if ((int) $intTercero == 6) {
$intUltimo = $strOriginal[8];
for ($indice = 0; $indice < 9; $indice++) {
//echo $strOriginal[$indice],'</br>';
switch ($indice) {
case 0:
$arrProducto[$indice] = $strOriginal[$indice] * 3;
break;
case 1:
$arrProducto[$indice] = $strOriginal[$indice] * 2;
break;
case 2:
$arrProducto[$indice] = $strOriginal[$indice] * 7;
break;
case 3:
$arrProducto[$indice] = $strOriginal[$indice] * 6;
break;
case 4:
$arrProducto[$indice] = $strOriginal[$indice] * 5;
break;
case 5:
$arrProducto[$indice] = $strOriginal[$indice] * 4;
break;
case 6:
$arrProducto[$indice] = $strOriginal[$indice] * 3;
break;
case 7:
$arrProducto[$indice] = $strOriginal[$indice] * 2;
break;
case 8:
$arrProducto[$indice] = 0;
break;
}
}
} else {
$intUltimo = $strOriginal[9];
for ($indice = 0; $indice < 9; $indice++) {
//echo $strOriginal[$indice],'</br>';
switch ($indice) {
case 0:
$arrProducto[$indice] = $strOriginal[$indice] * 4;
break;
case 1:
$arrProducto[$indice] = $strOriginal[$indice] * 3;
break;
case 2:
$arrProducto[$indice] = $strOriginal[$indice] * 2;
break;
case 3:
$arrProducto[$indice] = $strOriginal[$indice] * 7;
break;
case 4:
$arrProducto[$indice] = $strOriginal[$indice] * 6;
break;
case 5:
$arrProducto[$indice] = $strOriginal[$indice] * 5;
break;
case 6:
$arrProducto[$indice] = $strOriginal[$indice] * 4;
break;
case 7:
$arrProducto[$indice] = $strOriginal[$indice] * 3;
break;
case 8:
$arrProducto[$indice] = $strOriginal[$indice] * 2;
break;
}
}
}
foreach ($arrProducto as $indice => $producto)
$suma += $producto;
$residuo = $suma % 11;
$intVerificador = $residuo == 0 ? 0 : 11 - $residuo;
//echo "$intVerificador == $intUltimo";
return ($intVerificador == $intUltimo ? TRUE : FALSE);
}
function validarID($strId) {
switch (strlen($strId)) {
case 10:
return validarCI($strId);
break;
case 13:
return validarRUC($strId);
break;
default:
return FALSE;
}
}
public function beforeSave() {
echo $this->$CONT_CEDULA;
switch (strlen($this->$CONT_CEDULA)) {
case 10:
return validarCI($this->$CONT_CEDULA);
break;
case 13:
return validarRUC($this->$CONT_CEDULA);
break;
default:
echo "Numero de caracteres invalidos";
return FALSE;
}
//echo $op;
}
public function getSource() {
return 'SPM_CONTACTO';
}
public static function find($parameters = null) {
return parent::find($parameters);
}
public static function findFirst($parameters = null) {
return parent::findFirst($parameters);
}
By default Phalcon wont output any data you "echo" in your controllers or your models. The easy 'workaround' is to die('your output');
If you return a value in a switch, it is unnecessary to add a break; to the end of your case.
public function beforeSave()
{
// check the content of $this->$CONT_CEDULA
var_dump($this->$CONT_CEDULA);
die;
switch (strlen($this->$CONT_CEDULA)) {
case 10:
return validarCI($this->$CONT_CEDULA);
case 13:
return validarRUC($this->$CONT_CEDULA);
default:
// an example to test if your code enters this case.
die("Numero de caracteres invalidos");
return FALSE;
}
}

MySQL Select Not Returning resource

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'];

Categories