use variable inside function within function - php

i am trying to access $managers variable in change function.
public function ManagerPerDay() {
$query = $this->mysqli()->query('SELECT
manager,
count(manager) AS count
FROM
DATA
GROUP BY
manager
ORDER BY
count DESC');
$data = $query->fetch_all();
$managers = $this->GetManagers();
function Change($n)
{
$name = $managers[array_search($n[0], array_column($managers, 'id'))]['name'];
$n[0] = $name;
return $n;
}
$data = array_map('Change', $data);
array_unshift($data, ['Manager', 'Per Day']);
return $data;
}
i have tried global $managers; in change function but it also does not work.

Use array_walk which allows you to add your parameters
function Change(&$n, $key, $managers)
{
$name = $managers[array_search($n[0], array_column($managers, 'id'))]['name'];
$n[0] = $name;
}
array_walk($data, 'Change', $managers);

You could use the use keyword to pass that variable to the function. Something like this for example:
$data = array_map(function($n) use ($manager) {
$name = $managers[array_search($n[0], array_column($managers, 'id'))]['name'];
$n[0] = $name;
return $n;
}, $data);

Related

instances created in foreach loop are duplicates

I've written code that reads data from a cURL source which then processes it to extract records of data.
Each record becomes an instance of an object with several variables set from the data. A function extracts all the data and returns an array of objects.
The problem is that all of the objects have the same value which is the last record to be read from the source data.
After some testing I realize this is a reference problem. Data is read from the source and then assigned to an object which is then added to the array. The same object is reused in a loop that cycles through all the records in the source. Whenever this object is updated all previous values in the objects in the array are also reset to the newest value as they continue to reference the object when it is updated.
How can I make all the values independent?
function get_object_array () {
//reads raw data from cRUL source, returns array of objects
//array to hold objects
obj_arr = [];
//raw data has been split into array called $record, one element for each object
//loops through $record array
foreach ($record as $rec) {
//splits $rec into array of data called $data
//creates new object, but problem here as this object
//is being referenced by all values so last value
//changes all previous objects in array
$obj = new SaleItem();
//populates object with record data array
$obj->set_data($data);
//add object to array
$obj_arr [] = $obj;
}
return $obj_arr;
}
Update: Here is the function to set the data:
function set_data (array $arr) {
global $order_num, $name, $price, $cprice, $cheapest, $category;
try {
$order_num = (int)$arr[0];
$name = $arr[1];
$price = (float)$arr[2];
$cprice = (float)$arr[3];
$cheapest = $this->$price <= $this->$cprice ? true : false;
$category = $arr[5];
return true;
}
catch (Exception $ex) {
echo $ex;
return false;
}
}
Update: Full class code:
class SaleItem {
public $order_num = 12;
public $name = "";
public $price = 3.4;
public $cprice = 5.6;
public $cheapest = true;
public $category = "No Category";
function set_data (array $arr) {
try {
$this->order_num = (int)$arr[0];
$this->name = $arr[1];
$this->price = (float)$arr[2];
$this->cprice = (float)$arr[3];
$this->cheapest = $price <= $cprice ? true : false;
$this->category = $arr[5];
return true;
}
catch (Exception $ex) {
echo $ex;
return false;
}
}
function get_data () {
echo $this->order_num . ' num<br/>';
echo $this->name . ' name<br/>';
echo $this->price . ' price<br/>';
echo $this->cprice . ' cprice<br/>';
echo $this->cheapest . ' cheapest<br/>';
echo $this->category . ' category<br/>';
echo '<br/>';
}
}//end SaleItem class
You are using global variables instead of members. Remove
global $order_num, $name, $price, $cprice, $cheapest, $category;
From the function and preface each assignment with $this->
$this->order_num = (int)$arr[0];
$this->name = $arr[1];
$this->price = (float)$arr[2];
$this->cprice = (float)$arr[3];
$this->cheapest = $this->price <= $this->cprice;
$this->category = $arr[5];

N1QL prepared statement not working 100%

I have a problem where some variables are probably (I can't know for sure) not inserted into the final statement. Here is my example:
Works:
public static function findByPageAndFieldContains($recordsPerPage, $page, $field, $searchterm) {
$query = CouchbaseN1qlQuery::fromString('SELECT * FROM `public_portal` WHERE `collection`=$collection AND TOSTRING('.$field.') LIKE "%'.$searchterm.'%" ORDER BY `_id` limit $limit offset $offset');
$query->options['$collection'] = static::COLLECTION_NAME;
//$query->options['$field'] = $field;
$query->options['$limit'] = $recordsPerPage;
$query->options['$offset'] = $recordsPerPage*($page-1);
//$query->options['$searchterm'] = $searchterm;
$result = DB::getDB()->query($query);
var_dump($query);
var_dump($result);
$objects = array();
foreach($result as $row) {
$object = new static($row->{"public_portal"});
$object->setId($row->{"public_portal"}->{"_id"});
$objects[] = $object;
}
//var_dump($objects);
return $objects;
return $result;
}
Debug Output:
debug01
Does not work:
public static function findByPageAndFieldContains($recordsPerPage, $page, $field, $searchterm) {
$query = CouchbaseN1qlQuery::fromString('SELECT * FROM `public_portal` WHERE `collection`=$collection AND TOSTRING($field) LIKE "%$searchterm%" ORDER BY `_id` limit $limit offset $offset');
$query->options['$collection'] = static::COLLECTION_NAME;
$query->options['$field'] = $field;
$query->options['$limit'] = $recordsPerPage;
$query->options['$offset'] = $recordsPerPage*($page-1);
$query->options['$searchterm'] = $searchterm;
$result = DB::getDB()->query($query);
var_dump($query);
var_dump($result);
$objects = array();
foreach($result as $row) {
$object = new static($row->{"public_portal"});
$object->setId($row->{"public_portal"}->{"_id"});
$objects[] = $object;
}
//var_dump($objects);
return $objects;
return $result;
}
Debug output:
debug02
Basically the second example returns no result, while the first one works just fine.
Any idea why?
You are not using N1QL parameters correctly. You must decide if you are evaluating your parameters in PHP or in N1QL.
The field name cannot be a N1QL parameter, so you evaluate it in PHP:
TOSTRING('.$field.') LIKE ...
The search term should be a N1QL parameter, so you add wildcards in PHP and then pass it to N1QL as a parameter:
$searchterm = '%'.$searchterm.'%'
TOSTRING('.$field.') LIKE $searchterm ...

PHP function not returning correctly

So basically I have an array, and I have a function that will return an array value, but it is not returning anything.
$skills = array("Attack");
$i = 0;
$hs = file_get_contents("localhost/player=".$_GET["player"]);
foreach($skills as $value) {
$hs[$i] = explode(",",$hs[$i]);
$stats[$value]["rank"] = $hs[$i][0];
$stats[$value]["level"] = $hs[$i][1];
$stats[$value]["xp"] = $hs[$i][2];
$i++;
}
function getSkill($skill) {
//echo $skill;
return $stats[$skill]["level"];
}
I have tried getSkill("Attack"); and it doesn't work;
but if I do echo $stats["Attack"]["level"]; it works fine.
You don't pass the $stats array to your function so it can't know what is in it.
function getSkill($stats, $skill) {
//echo $skill;
return $stats[$skill]["level"];
}
and call it with getSkill($stats,"Attack");

Php: Array returning empty

I am stumped on my array is not being saved after having values added to it in the functions. I believe it is a problem with the variables not being in the scope of the function. I have the following variables:
$oldInterestIdArray = array();
$newInterestsIdArray = array();
and I have some functions to populate the arrays:
function oldInterestIds($value, $key)
{
$data = fetchInterestDetail($value);
$id = $data['id'];
$oldInterestIdArray[] = $id;
}
function getNewInterestIds($value,$key)
{
if(interestExists($value))
{
$data = fetchInterestDetail($value);
$id = $data['id'];
$newInterestsIdArray[] = $id;
}
else
{
addInterest($value);
$data = fetchInterestDetail($value);
$id = $data['id'];
$newInterestsIdArray[] = $id;
}
}
if(count($errors) == 0)
{
$newInterests = array_diff($interestsArray, $interests);
$common = array_intersect($interestsArray, $interests);
$toChangeId = array_diff($interests, $common);
array_walk($toChangeId, "oldInterestIds");
array_walk($newInterests, "getNewInterestIds");
echo json_encode($oldInterestIdArray);
}
}
But the $oldInterestIdArray is returning blank. But if I were to echo json inside the oldInterestIds function it works, which leaves me to believe this is a problem with the variables scope. I have tried changing the variable to:
global $oldInterestIdArray;
global $newInterestsIdArray;
But that is returning null. Any suggestions?
declare global $oldInterestIdArray; inside the function like
function oldInterestIds($value, $key)
{
global $oldInterestIdArray; // set here global;
$data = fetchInterestDetail($value);
$id = $data['id'];
$oldInterestIdArray[] = $id;
}
See Example
Pass your array in as a reference :
function oldInterestIds(&$arr, $value, $key)
{
$data = fetchInterestDetail($value);
$id = $data['id'];
$arr[] = $id;
}

How to make first array value to uppercase

I am trying to make first array value to uppercase.
Code:
$data = $this->positions_model->array_from_post(array('position', 'label'));
$this->positions_model->save($data, $id);
So before save($data, $id) to database I want to convert position value to uppercase. I have tried by this
$data['position'] = strtoupper($data['position']);
but than it is not storing the value in db with uppercase but as it is what user inputs.
Current output of $data:
Array ( [position] => it [label] => Information Technology )
And I want it in uppercase as IT
Added Model Method
public function get_positions_array($id = NULL, $single = FALSE)
{
$this->db->get($this->_table_name);
$positions = parent::get($id, $single);
$array = array();
foreach($positions as $pos){
$array[] = get_object_vars($pos);
}
return $array;
}
Main MY_Model method
public function array_from_post($fields)
{
$data = array();
foreach ($fields as $field) {
$data[$field] = $this->input->post($field);
}
return $data;
}
This should work:
$data = $this->positions_model->array_from_post(array('position', 'label'));
$data['position'] = strtoupper($data['position']);
$this->positions_model->save($data, $id);
If Its not, then $data array have only read attribute.
The array_from_post() method returns an array with the format below:
$data = array(
'position' => 'it',
'label' => 'Information Technology'
);
So, you could make first value of the array to uppercase, by using array_map or array_walk functions as follows:
$data = array_map(function($a) {
static $i = 0;
if ($i === 0) { $i++; return strtoupper($a); }
else return $a;
}, $array);
Note: This only works on PHP 5.3+, for previous versions, use the function name instead.
Here is the array_walk example, which modifies the $data:
array_walk($data, function(&$value, $key) {
static $i = 0;
if ($i == 0) { $i++; $value = strtoupper($value); }
});
Again, if you're using PHP 5.2.x or lower, you could pass the function name instead.

Categories