Query gives one indexed array with many elements - php

I have code like this:
$ch = #new mysqli ($config['db']['host'],$config['db']['user'],$config['db']['password'],$config['db']['database']);
if($result = $ch->query("SELECT pid FROM posts"))
{
while($pids = $result->fetch_assoc())
{
var_dump($pids);
}
var_dump gives me:
array(1) { ["pid"]=> string(1) "1" } array(1) { ["pid"]=> string(1) "2" } array(1) { ["pid"]=> string(1) "3" } array(1) { ["pid"]=> string(1) "4" }
I have two problems:
In database column 'pid' is an int type but the query yields an array of strings
All records from database (4) are saved in one row in an array (got only one index)
Because of that I can't use max(), because it gives me all records (4321).

You have got 4. Check correctly. The var_dump() executes four times, returning a single array (column - row values):
array(1) {
["pid"]=> string(1) "1"
}
array(1) {
["pid"]=> string(1) "2"
}
array(1) {
["pid"]=> string(1) "3"
}
array(1) {
["pid"]=> string(1) "4"
}
If you want everything to be in a single variable, use:
$allPids = array();
while (false != ($pids = $result->fetch_assoc())) {
$allPids[] = $pids;
}
var_dump($allPids);

You need to store them in one array first.
while($pids = $result->fetch_assoc())
{
$array[] = $pids;
}
var_dump($array);
And for the data type PHP will cast them accordingly.

Related

Array data manipulations PHP

I get from my DB data in format like this:
array(12) {
[0]=>
array(4) {
["id"]=>
string(1) "1"
["count"]=>
string(5) "78984"
["month"]=>
string(1) "6"
["hours"]=>
string(10) "10580.0833"
}
[1]=>
array(4) {
["id"]=>
string(1) "2"
["count"]=>
string(5) "64174"
["month"]=>
string(1) "6"
["hours"]=>
string(9) "6866.8333"
}
[2]=>
array(4) {
["id"]=>
string(1) "3"
["count"]=>
string(5) "31032"
["month"]=>
string(1) "6"
["hours"]=>
string(9) "3700.9167"
}
[3]=>
array(4) {
["id"]=>
string(1) "1"
["count"]=>
string(5) "91114"
["month"]=>
string(1) "7"
["hours"]=>
string(10) "11859.6000"
}
...
Each of array inside has a key: "id". It mostly look values from 1 to 3. I would like to create a new array based on this "ids" that would look like this:
array("number of unique ids") {
[0]=> "for id = 0"
array(12) {
int() count/hours
int() count/hours
int() count/hours
...
}
[1]=> "for id = 1 and so on..."
array(12){
....
}
I`ve been trying to do it like this:
$data1 = [];
$data2 = [];
$data3 = [];
foreach($data as $key => $record){
if($record['id'] == 1){
array_push($data1, $record['count']/$record['hours']);
}else if($data['id_zmiana'] == 2){
array_push($data2, $record['count']/$record['hours']);
}else{
array_push($data3, $record['count']/$record['hours']);
}
}
$raport = array_merge($data1, $data2, $data3);
And that would work, but it doesn`t look good in my opinion, beacuse what if the id change to some big number.
Yeah, having separate arrays for each ID is not a good idea. How about:
$raport = [];
foreach ($data as $record) {
$raport[$record['id']][] = $record['count'] / $record['hours']);
}
Simple, and straight to the point.
Haven't tested it. Next time try to use var_export() to export the data you put in your question. That way we can actually use it, without having to rewrite it completely.

ECHO of an object breaking page

I have the following code that when used breaks my page. What am I not doing correctly?
$check_availability = $wpdb->get_results($wpdb->prepare("SELECT id FROM mytablename "));
foreach ($check_availability as $available){
echo $available . "<br>\n";
}
Ive tried moving the echo out of the loop. Same broken page result. This worked correctly when I had NO foreach loop at all but then it would only return 1 result instead of many.
EDIT 1 to show var_dump($available) result inside the loop -
object(stdClass)#2314 (1) { ["id"]=> string(1) "4" } object(stdClass)#2361 (1) { ["id"]=> string(1) "6" }
If I var_dump($check_availability ) outside of the loop then I get
array(2) { [0]=> object(stdClass)#2314 (1) { ["id"]=> string(1) "4" } [1]=> object(stdClass)#2361 (1) { ["id"]=> string(1) "6" } } array(2) { [0]=> object(stdClass)#2314 (1) { ["id"]=> string(1) "4" } [1]=> object(stdClass)#2361 (1) { ["id"]=> string(1) "6" } }
The "echo" function can only print strings / numbers.
In this case you are trying to print an object.
If you want to print the id try writing:
$check_availability = $wpdb->get_results($wpdb->prepare("SELECT id FROM mytablename "));
foreach ($check_availability as $available){
echo $available->id . "<br>\n";
}
If you are interested in knowing what '$available' contains, run this:
$check_availability = $wpdb->get_results($wpdb->prepare("SELECT id FROM mytablename "));
foreach ($check_availability as $available){
var_dump($available);
}

search multi-dimentional array for matching elements

I have a multi dimensional array. I need to search through the arrays and retrieve instance of dates that match each other.
This is my array:
$dateArray = array(8) {
[0]=>
array(15) {
["bookable_id"]=>
string(1) "1"
["event_date"]=>
string(10) "2019-09-11"
}
[1]=>
array(15) {
["bookable_id"]=>
string(1) "1"
["event_date"]=>
string(10) "2019-09-11"
}
[2]=>
array(15) {
["bookable_id"]=>
string(1) "4"
["event_date"]=>
string(10) "2019-10-17"
}
[3]=>
array(15) {
["bookable_id"]=>
string(1) "4"
["event_date"]=>
string(10) "2019-10-17"
}
[4]=>
array(15) {
["bookable_id"]=>
string(1) "3"
["event_date"]=>
string(10) "2020-09-15"
}
[5]=>
array(15) {
["bookable_id"]=>
string(1) "3"
["event_date"]=>
string(10) "2020-09-15"
}
[6]=>
array(15) {
["bookable_id"]=>
string(1) "2"
["event_date"]=>
string(10) "2021-09-09"
}
}
This is my function:
function searchMatchingDates($compare, $array)
{
foreach ($array as $val) {
if ($compare["event_date"]== $val["event_date"]){
return $val;
}
}
return null;
And this is how i searched it:
foreach ($dateArray as $compare) {
$match = searchMatchingDates($compare, $array);
}
if($match){
echo "$compare['bookable_id'] + $match['bookable_id']; "
}
This works and return the date. It however return duplicate dates as the array will compare twice.
I need a way to remove an array once an array has been compared once .
For example, once array once has ran its iteration it needs to be removed so that the next array does not do a comparison on it.
If I understand the question, you want to return the dates which feature more than once in the array?
You could do this by counting all of those which feature more than once (array_count_values() https://www.php.net/manual/en/function.array-count-values.php combined with array_column()), then filtering the array based on that outcome.
// get dates which feature more than once
$dateCounts = array_filter(
array_count_values(array_column($dateArray, 'event_date')),
function ($count) {
return $count > 1;
}
);
// filter those matching dates
$matching = array_filter($dateArray, function ($date) use ($dateCounts) {
return isset($dateCounts[$date['event_date']]);
});
var_dump($matching);

output of array always equals 'i'

I have the variable $request. If i do vardump($request), I get the output of:
array(7) {
["controller"]=> string(5) "index"
["action"]=> string(5)"index"
["module"]=> string(7) "default"
[2]=> array(8) {
["g_goal_list_id"]=> string(3) "127"
["textgoal"]=> string(9) "eats food"
["task_0"]=> string(1) "0"
["value_0"]=> string(5) "pukes"
["task_1"]=> string(1) "0"
["value_1"]=> string(0) ""
["task_2"]=> string(1) "0"
["value_2"]=> string(0) ""
}
[3]=> array(10) {
["g_goal_list_id"]=> string(3) "128"
["textgoal"]=> string(9) "goes home"
["task_0"]=> string(1) "0"
["value_0"]=> string(20) "but never comes back"
["task_1"]=> string(1) "0"
["value_1"]=> string(14) "stays home now"
["task_2"]=> string(1) "0"
["value_2"]=> string(0) ""
["task_3"]=> string(1) "0"
["value_3"]=> string(0) ""
}
["submit"]=> string(4) "Save"
["task"]=> string(1) "5"
}
which is all correct. However, I'm trying to use a foreach statment to grab values from the $request array and put them into a data array, and then submit that to the mysql db...
foreach($request as $currentrow){
//skips row if the field is empty
if(strlen($currentrow['value']) < 1)//need to make sure I've defined $currentrow['value']
continue;//skips row with empty field
//I only need to grab the value/list_id/account_id from the form
$data = array('value' => $currentrow['value'],
'g_goal_list_id' => $currentrow['g_goal_list_id'],
'account_id' => g_getAccountId(),
);
var_dump($data);
However, when I var_dump($data); my output looks like this:
array(3) { ["value"]=> string(1) "i" ["g_goal_list_id"]=> string(1) "i" ["account_id"]=> string(1) "1" }
array(3) { ["value"]=> string(1) "S" ["g_goal_list_id"]=> string(1) "S" ["account_id"]=> string(1) "1" }
array(3) { ["value"]=> string(1) "5" ["g_goal_list_id"]=> string(1) "5" ["account_id"]=> string(1) "1" }
The only thing that is correct in that var_dump($data) is the ["account_id"]
I'm thinking that my loop is incorrect, and I'm pretty bad with loops. Sooooo yeah, hopefully I included enough information. Thank you.
What you need is something like this:
foreach($request as $k=>$currentrow)
{
$hit = false;
$data = array();
// Only look for sub-arrays
if(is_array($currentrow))
{
foreach($currentrow as $k2=>$v2)
{
$explode = explode('_', $k2);
if($explode[0] === 'value') //need to make sure I've defined $currentrow['value'] regardless of suffix
{
$hit = true;
$data = array(
'value' => $v2,
'g_goal_list_id' => $currentrow[$k]['g_goal_list_id'],
'account_id' => g_getAccountId(),
);
continue;
}
}
}
if($hit === false)
{
continue;
}
var_dump($data);
}
This element: $currentrow['values'] does not exist (check your logs, you should see notices). Neither does $currentrow['g_goal_list_id'].
You loop through an array with all different elements, the first being a string, with value index. When you then take that string and subscribe that with values, it throws a warning, but then takes the first element.
To clarify, a some CLI code:
php > $a="abcd";
php > echo $a["foo"];
PHP Warning: Illegal string offset 'foo' in php shell code on line 1
a
If you want to loop over keys and values, do like this:
foreach($request as $key=>$value) {
}
That being said, I think a loop is not what you want, you do not have straighforward table-like data.
Huge thanks to #MonkeyZeus. I kept on getting an array that had the proper keys but all the values were null. Turns out I just needed to put my var_dump($data) inside of my loop, because when it was on the outside it was returning only the last array it looped thorough. On my form the last values it loops through were empty fields, that are meant for the user to add input. Also, I had to change 'g_goal_list_id' => $currentrow[$k]['g_goal_list_id'] to just 'g_goal_list_id' => $currentrow['g_goal_list_id']
foreach ($request as $k=> $currentrow) {
$hit = false;
$data = array();
if(is_array($currentrow)){
foreach ($currentrow as $k2 => $v2) {
$explode = explode('_', $k2); //blows off the suffix of the $key
//var_dump($explode);
//$explode=substr($explode,2);
//echo $k2;
//echo '******';
//echo $v2;
echo $explode[0];
echo '/';
if($explode[0] == 'value'){
//echo "[" . $currentrow['g_goal_list_id'] . "]";
$hit = true;
$data = array(
'value' => $v2,
'g_goal_list_id' => $currentrow['g_goal_list_id'],
'account_id'=> g_getAccountId(),
);
continue;
}
var_dump($data);
}
}
if ($hit === false){
continue;
}
break;
}

Return result form query - showing only on one row

it's simple, but I can't do it. I have a query and I want query result to be shown only once. In my code, name of the course is shown so many times as my rows are. I use Codeigniter. My code is:
foreach ($timetable as $row) {
echo $row->course_name;
}
My query is:
public function select_timetable() {
$this->db->select('sequence_num, topic, courses_specific_id, courses_common.course_name,
courses_specific.course_place, courses_common.courses_common_id, timetable.timetable_id');
$this->db->from('timetable');
$this->db->join('courses_common', 'courses_common.courses_common_id=timetable.courses_common_id');
$this->db->join('courses_specific', 'courses_specific.courses_common_id=courses_common.courses_common_id');
$this->db->where('courses_specific_id', $this->input->post('courses_specific_id'));
$result=$this->db->get();
return $result->result();
}
And the result of var_dump($timetable[0]) is:
object(stdClass)#27 (7) {
["sequence_num"]=> string(1) "1"
["topic"]=> string(10) "HTML tags "
["courses_specific_id"]=> string(1) "1"
["course_name"]=> string(4) "HTML"
["course_place"]=> string(6) "Center"
["courses_common_id"]=> string(1) "1"
["timetable_id"]=> string(1) "1"
}
HTMLobject(stdClass)#27 (7) {
["sequence_num"]=> string(1) "1"
["topic"]=> string(10) "HTML tags "
["courses_specific_id"]=> string(1) "1"
["course_name"]=> string(4) "HTML"
["course_place"]=> string(6) "Center"
["courses_common_id"]=> string(1) "1"
["timetable_id"]=> string(1) "1"
}
HTMLobject(stdClass)#27 (7) {
["sequence_num"]=> string(1) "1"
["topic"]=> string(10) "HTML tags "
["courses_specific_id"]=> string(1) "1"
["course_name"]=> string(4) "HTML" ["course_place"]=> string(6) "Center" ["courses_common_id"]=> string(1) "1" ["timetable_id"]=> string(1) "1" } HTML
To access the the results you have to do something like:
<?php
foreach ($timetable->result() as $row)
{
echo $row->course_name;
}
?>
If you wanted to only show one row you would need to do something like:
if ($timetable->num_rows() > 0)
{
$row = $timetable->row_array();
echo $row['course_name'];
}
You can also walk through your different rows like:
$row = $timetable->first_row()
$row = $timetable->last_row()
$row = $timetable->next_row()
$row = $timetable->previous_row()

Categories