using list() constructer for array - php

I have multiple dates to calculate on database. They are fetched and stored in an array.
How can I have variables for each of the returned values, since I don't know how many of the dates are returned?
Here is what I tried so far:
$get_status = $truckerController->status($gid);
$active_days = 0;
$active_d = array();
foreach ($get_status as $trucker) {
$active_d[] = $trucker->date;
}
list($date1, $date2) = $active_d;
So what I want is to have more than two or three parameters inside list() based on the array value size. Please help me out or suggest other ways to handle this issue.

Not sure if the whole approach is correct, but you can try with something like this.
$get_status = $truckerController->status($gid);
$active_days = 0;
$active_d = array();
$i = 0;
foreach ($get_status as $trucker) {
$i++;
$active_d["date".$i] = $trucker->date;
}
extract($active_d);
http://php.net/manual/en/function.extract.php

Related

PHP/MySQLi - Combining for and while

I'm attempting to combine two pages into one for simplicity, however to do so, I need to find a way to combine a for() loop from one page with a while() loop from the other page, so that they both work in the same way.
This is what they currently are:
for($i = 0; $i < $count; $i++) {
and
while($widget = $grabWidget->fetch_array()) {
As you may see, the for() loop does not loop through a MySQLi query, but rather an array of values which are identical to that of what is also in a database.
The second while() loop grabs a set of identical values from the database. However they both must stay on their current bases.
My question is, can both loops be combined into one, while still being able to loop through individual database and array elements?
Thanks in advance :)
EDIT: As requested, here are both the usages for the loops.
if($grabWidget = $db->query("SELECT * FROM editor_widgets"))
{
while($widget = $grabWidget->fetch_array())
{
$id = $core->input($widget[1]);
$coords[0] = $core->input($widget[4]);
$coords[1] = $core->input($widget[5]);
$temp = $core->input($widget[2]);
$content_out = $core->output($widget[3],true);
and
if(isset($_POST['widgets']))
{
$widget = $_POST['widgets'];
$count = count($widget);
for($i = 0; $i < $count; $i++)
{
$id = $core->input($widget[$i][0]);
$content_in = $core->input($widget[$i][1]);
$coords[0] = $core->input($widget[$i][2][0]);
$coords[1] = $core->input($widget[$i][2][1]);
$temp = $core->input($widget[$i][3]);
$content_out = $core->output($widget[$i][1],true);
The new simplified page must have the ability to loop through from either an array OR a MySQLi query. So basically, I want to use the for() loop and have it also work with MySQLi
Add an interator $i thats in while thats it.
$i=0;
while($widget = $grabWidget->fetch_array()) {
++$i;
// YOUR CODE
}

Sort flat file array

I'm trying to sort data alphabetically by the COMPANY NAME from a flat file. I was thinking that a simple sort would handle this, but I was wrong. I now think that I need to use usort and cmp and then create another temp array. How can I accomplish this?
This is my current code.
$data_file = fopen($data_file_url, "r");
fgets($data_file); // IGNORE FIRST LINE IN FLATFILE - column names
while (!feof($data_file) ) {
$data_lines = fgets($data_file);
$data_ele = explode('|', $data_lines);
$company_name = $data_ele[0];
$section = $data_ele[1];
$category = $data_ele[2];
$service = $data_ele[3];
$service = substr_replace($service,"",-1); // trim last char
}
You should first store all elements in a big array and afterwards sort it using a callback:
$data_file = fopen($data_file_url, "r");
fgets($data_file); // IGNORE FIRST LINE IN FLATFILE - column names
$companies = array();
while (!feof($data_file) ) {
$data_lines = fgets($data_file);
$data_ele = explode('|', $data_lines);
$row = array();
$row['company_name'] = $data_ele[0];
$row['section'] = $data_ele[1];
$row['category'] = $data_ele[2];
$row['service'] = $data_ele[3];
$row['service'] = substr_replace($row['service'],"",-1); // trim last char
$companies[] = $row;
}
usort($companies, function ($a, $b) {
return strcmp($a['company_name'], $b['company_name']);
});
Please note: I'm using an anonymous function, introduced in PHP 5.3.0.
I would imporove upon Beats answer only by using the company name as a key in the array.
If you have multiple entries per company have a sub array.
By using the key as array it is already indexed when inserted.
I believe its faster.
You could also use fgetcsv here, which is also probably a little faster.

random shuffle in php?

I'm creating a lottery to pair up people. So I want a way to shuffle the strings in an array where no item ends up on the same place. (You can't pair up with yourself)
public function shuffleSantas(){
$query = $this->db->get('person');
$givers = array();
$recievers = array();
foreach($query->result() as $row):
$givers[] = $row->name;
//here i want a random order, but no name can be on the same place as in $givers!
$recievers[] = '';
endforeach;
shuffle the array once and then pair up the first element with the second, the second with the third etc. and the last with the first.
$src = $query->result();
$givers = array();
$receivers = array();
foreach ($src as $idx=>$first_person){
$count = 0; //infinite loop guard
do{
++$count;
$sec_idx = rand(0,count($src)-1);
$second_person = $src[$sec_idx];
} while ($second_person==$first_person && $count<5);
$givers[] = $first_person;
$receivers[] = $second_person;
}
In this case one will be able to receive from one person and to give to other person. Is it OK? Also, this algorithm is not optimal and will definitely fall into infinity loop if there is only one person in an array.
If think there is no built-in function in PHP to shuffle that way. You have to write your own function.

Fatal error, not quite sure why?

I think this is just something I haven't come across before!
$r = $database->currentChallengers($f, $g);
while($row=mysql_fetch_assoc($r))
{
$u[]=$row['username'];
$i[]=$row['userid'];
$s[]=$row['streak'];
}
for ($i = 0; $i < count($u); $i++)
{
foreach ($u as $user)
{
echo "Challenger: $u[$i]";
}
}
That PHP is for the following database query:
function currentChallengers($f, $g)
{
$q = "SELECT k.userid, k.streak, u.username
FROM ".TBL_KOTH." k
INNER JOIN ".TBL_USERS." u
ON k.userid = u.id
WHERE k.format = '$f' && k.game = '$g' && k.king = '0' && k.done = '0'
ORDER BY k.userid";
return mysql_query($q, $this->connection);
}
I am getting the error
Fatal error: [] operator not supported for strings
On the line
$u[]=$row['username'];
Could anyone tell me why this is happening?
Also, should the code I have written list each username from the query?
Thanks
The other answers already point out what you need to do: Use an array. But before that, check whether $u etc. are being used somewhere else in the code already. You could get in trouble because they may already be in use elsewhere - as strings.
And, you should really use some more verbose variable names to avoid building a maintenance nightmare. Why not use for example
$username[] = $row['username'];
$userid[] = $row['userid'];
$streak[] = $row['streak'];
}
PHP seems to be assuming your uninitialized variables are strings. See Pekka's Answer. Try initializing/declaring those variables before you start pushing values onto them.
$u = array();
$i = array();
$s = array();
Use meaningfull variable names.
You have used $u to store a string somewhere above this code.
Probably you stored a username in it.
So I recommend using variables $username and $users.
And set $users = array(); before a loop, as proposed by Mike/
What are you trying to do with $u[]=$row['username'];? $u is currently a string and you can't write to a specific index of a string (you haven't specified any index either).
If you're trying to store rows in to arrays, declare them as arrays and use an iterating variable to populate it.
$u = array();
$i = array();
$s = array();
$k = 0;
while($row=mysql_fetch_assoc($r))
{
$u[$k] = $row['username'];
$i[$k] = $row['userid'];
$s[$k] = $row['streak'];
$k = $k + 1;
}
Try this, instead of arrays :
$u=$row['username'];
$i=$row['userid'];
$s=$row['streak'];
Are you sure that $u is not already defined? Initialize it with $u = array(); before the first "while"...
The problem seems to come to the fact that $u (and possibly $s and $i) seems to be a string.
Try adding:
$u = array();
$s = array();
$i = array();
before:
$r = $database->currentChallengers($f, $g);
You should add $u = array() before accessing it. You probably use some other $u as a string in another part of your script and PHP still believe it's the same one.

how to grab a "random" set of items from a loop in php

Im looping through some XML nodes, and say i have between 1 and 200 of these nodes.
How can i "randomly" select a maximum of 10 of these nodes. It has to be as most ten, but as few as 1.
This is what im working with now...
$i = 0;
foreach ($butters->users->user as $user) {
if($i==10) break;
$id = $user->id;
$name = $user->screen_name;
$profimg = $user->profile_image_url;
echo "things";
$i++;
}
The difficulty is that i don't know how many i will have, but would like the pool from which i select my "random" 10 to be from the entirety of however many are present.
$randomPool = array_rand ( $butters->users->user, 10 );
I'd get the 10 random indexes, then loop through those and get the nodes.
$indexes = array();
for($i = 0; $i< 10; $i++){
$indexes[] = rand(0, $butters->users->length);
}
foreach($indexes as $index){
$user = $butters->users->item($index);
//do whatever with $user
}
You'll need to add a check to make sure that you have not already got the index when you add it to the $indexes array.
You could put this into one command, however you may end up with duplicates (unlikely depending on the amount of elements, but possible...
for($i = 0; $i< 10; $i++){
$user = $butters->users->item(rand(0, $butters->users->length));
//do something with $user
}
Put all users in an array, shuffle it and grab the first ten items:
$users = array[];
foreach ($butters->users->user as $user) {
$users[] = &$user;
}
shuffle($users);
$tenRandomUsers = array_slice($users, 0, 10);
Maybe you can shorten the first step with just $users = (array) $butters->users->user.
Create a random object (don't know the PHP specific code) then call it and compare with 10 / (total in the set). This means you should in theory select 10%, however it could be less, and your exiting code stops it from selecting more.
Assuming you are using SimpleXML, you could use an XPath to get all the users. This will return an array and from that it should be cake.
Something like this should do:
$users = $xml->xpath('//butters/users/user');
$random = array_rand($users, 10);
Someone might want to correct me on the Xpath though. Doing it from memory
if you have some sort of strange self-implemented data structure for $users you might want to use reservior sampling -- Efficiently selecting a set of random elements from a linked list

Categories