Accessing object's properties via array index - php

I have a situation where i have to programmatically do database inserts. I have multiple tables but the order of information of those tables are similar , i.e, in each table, the first coulmn in id, and second is a foregin key, and third is a name, and fourth is a blob and fifth is a text.
I searched php doc and found that I can use $objectName[index] to access the database property. I am getting error
Cannot use object of type stdClass as array in C:\....php on line .. .
The erroneous line is indicated on the code
private function uploadTemp($databaseObject, $table_name){
$this->load->database();
//get file_contents too;
$file_id = $databaseObject[3]; // < Here's where the error appeared
$this->db->from('tbl_file')->where('file_id',$file_id);
$q = $this->db->get();
$data = $q->row();
$query = "INSERT INTO $table_name VALUES(NULL, '".$databaseObject[2]."','".$data->filecontent."');";
$this->db->query($query);
}
I am using CodeIgniter as a framework.

Try casting to array:
$file_id = (array) $databaseObject[3];
As STDClass is just a dummy container with public dynamic variables and no methods, there should be no problems in casting it to array and backwards as well.
However in some situations numbers are used to represent a variable name.
Example:
$array ; //Is some array created by engines / database handlers.
$obj = (object) $array ;
echo $obj->0 ; //Hell it will not work.
echo $obj[0] ; //The same problem.
echo $obj->{'0'} ; //PERFECT

try this function get_object_vars()
or create function to convert to array
function array_to_object($array)//from CodeIgniter forum
{
return (is_array($array)) ? (object) array_map(__FUNCTION__, $array) : $array;
}

Related

Unable to get Joomla fieldparams as array or object

I would get Joomla custom fields values from a PHP script. I include all necessary files and I can read checkbox values from "fields" table, the "fieldparams" column.
If I execute this code
$query = "select #__fields.fieldparams from #__fields where #__fields.id = 19";
$db->setQuery($query);
$result = $db->loadRowList();
foreach ($result as $value) {
echo gettype($value); // 01
echo $value[0]; // 02
$var = json_encode($value[0]);
echo gettype($var); // 03
}
the type of $value is "Array" (step 01), so if I access to $value[0] the result (step 02) is the global list (so I suppose this is an Array with 1 element)
{
"options":{
"options0":{"name":"type1","value":"1"},
"options1":{"name":"type2","value":"2"},
"options2":{"name":"type3","value":"3"},
"options3":{"name":"type4","value":"4"},
"options4":{"name":"type5","value":"5"}
}
}
but when I try to use json_encode the result (step 03) is a string.
In this way I can't access to keys and relative values.
What's wrong?
There are 2 issues here. 1. You're using ->loadRowList() which is a method designed to return an array of rows (i.e. multiple rows), not one as is implied by your where clause, and 2. Rather than using PHP's native functions, try using Joomla's JRegistry class instead.
To address these points:
1 Since you're only expecting 1 row to be returned (field with ID 19), replace your line:
$result = $db->loadRowList();
with
$result = $db->loadResult();
$result will contain the fieldparams column only.
2 Create an instance of the JRegistry class so we can access the key => value pairs:
// new registry
$registry = new JRegistry();
$registry->loadString($result); // load the string from the db
// if you need an array, use jregistry's toArray method
$arrayData = $registry->toArray();
Hope it helps,
Gez

Accessing items within a PHP array object

I have an array of the record retrieved from a SQL server database stored in an object $result. I will like to access each item in the array object and print it out to the screen. How can I achieve this? My attempt is below
$result = $DB->get_records_sql("SELECT rawname, ID FROM mdl_tag where tagType = 'institution'");
$result = array();
foreach ($result as $ $value) {
echo $value;
);
}
Here is the correct code:
// Get results from table 'tag', where 'tagtype' matches 'institution', with no sorting and returning fields 'id' and 'rawname'.
$results = $DB->get_records('tag', ['tagtype' => 'institution'], '', 'id, rawname');
foreach ($results as $value) {
echo $value->rawname;
}
So, there are a number of issues:
Use get_records, unless you really need to use get_records_sql.
If you do need to use get_records_sql, then the table is called {tag} not mdl_tag, otherwise you'll run into problems on any server that uses a prefix other than 'mdl_' (e.g. when running phpunit or behat tests).
Writing $result = array(); immediately before looping through the result will throw away the details from the database and replace them with an empty array
The results from get_records (or get_records_sql) are an array containing objects, each of which contains the values for the requested fields, so you need to access the individual value, not try to echo the entire object
All database fields in Moodle are lowercase, so 'tagtype' not 'tagType', 'id' not 'ID'.

Best practice OOP with MVC and PHP functions?

New to OOP so I am trying to figure out best practice. This code is based off an existing script I am adding to.
Most of the threads with this question tell the poster to code as so:
function ($arg1, $arg2){
//some code
}
and call:
function($a1, $a2);
I have an OOP-based function (that works) but it doesn't quite look right and when I try to call it as the suggested method, I get:
Array to string conversion .... on line .. Array
Here's my (working) function that gathers the output:
public function getMail($type, $id = 0) {
$query = $this->db->query("SELECT * FROM km_mail WHERE id = '" . (int)$id . "' AND `type` = '" . $this->db->escape($type) . "'");
foreach ($query->rows as $result) {
$mail_data[$result['title']] = $result['value'];
}
return $mail_data;
}
This is the working (but ugly) part - this returns the database column requested (but looks wrong?):
$this->model_setting_mail->getMail('order')['update_link'];
When I try to request the column like so, the array to string conversion error occurs:
$this->model_setting_mail->getMail('order','update_link');
In my example, order = $type, update_link = $result['value'] and $id = 0 is default, unless an $id is passed.
The first example you show is a shorthand way of selecting an array element from value returned by a function.
$this->model_setting_mail->getMail('order')['update_link'];
Is the same as:
$result = $this->model_setting_mail->getMail('order');
print $result['update_link'];
Second example is passing two values to a function.
They are completely different.

Create array with key and value in loop PHP

I'm using PDO, and I managed to get the table columns despite the table name and create the bind variables, like in ... VALUES (:foo, :bar);.
The method I'm trying to do this is insert().
public function insert()
{
// the variable names depend on what table is being used at the moment the script runs.
// These methods use the PDO `getColumnMeta()` to retrieve the name of each column
$sql = "INSERT INTO {$this->getTableName()}({$this->getTableColumns()}) "
. "VALUES ({$this->getTableColumns(true)})";
// The previous method gets the name of each column and returns a single string, like "foo, bar, [...]"
// and this function is used to separate each word, with the specified delimiter
$col = explode(", ", $this->getTableColumns());
// Now here lays the problem.
// I already know how to retrieve the columns name as a variable, and
// how to dynamically create the get method, using `ucfirst()`
// What I need would be something like this being inside of a
// loop to retrieve all the separated words from `$col` array.
$data = array(
$col[$i] => "\$this->entity->get".ucfirst($col[$i])."()",
)
/*
* From now on, is what I need to do.
*/
// Lets pretend the column names are "foo, bar".
$data = array(
":foo" => $this->entity->getFoo(),
":bar" => $this->entity->getBar()
)
// That'd be the final array I need, and then continue with
$stm = $this->db->prepare($sql);
$stm->execute($data);
}
You have to loop over $data array and add function as per your requirement.
Fetch values from `... VALUES (:foo, :bar); Then explode as you did in your code , then loop over $col array and add values to $data as required
foreach($col as $val){
$method = "get".ucfirst( $val);
$data[ $val] = call_user_func(array( $this->entity,$method));
}
Above code may work as follow
$data[':foo'] = $this->entity->getFoo();
$data[':bar'] = $this->entity->getBar();

Unsure as to how certain sections of this function work

While writing a login system for a web project Im working on I came across the problem of binding an unknown number of parameters and found this function on the php manual pages. I always like to fully understand an peice of code I put into anything Im working on and Im quite stumped as to how a few sections of this function work.
Ive commented everything I think i understand(if im wrong please let me know) and left my major questions in the comments:
<?php
function getresult($stmt) {
//Define var for holding the result
$result = array();
//asign metadata of the statments result
$metadata = $stmt->result_metadata();
//grab the feilds from the metadata and assign to var
$fields = $metadata->fetch_fields();
//for loop with internal break
for (;;) {
//pointers array (not sure why this is an array and not a stdClass)
$pointers = array();
//row empty class
$row = new stdClass();
//set pointers array to the value of the passed statement (casting $pointers to mysqli_stmt class I assume(?)
$pointers[] = $stmt;
//iterate through all fields
foreach ($fields as $field) {
//each time set $fieldname to the name from the current element of $fields
$fieldname = $field->name;
//?? this is my big issue no idea whats going on here $row hasnt been set from what i can see, and no idea why its being refered to by reference and not value
$pointers[] = &$row->$fieldname;
}
//call bind result for all values
call_user_func_array(mysqli_stmt_bind_result, $pointers);
//internal break if
if (!$stmt->fetch()) {
//if there is nothing left to fetch break
break;
}
//set the result
$result[] = $row;
}
//free resources
$metadata->free();
//return result
return $result;
}
?>
Thanks in advance!
It creates a new stdClass (pretty much like an empty array) for each row.
With $pointers[] = &$row->$fieldname; a reference to the various fields of the object is stored.
After that, mysqli_stmt_bind_result is used to tell mysqli where to store the data of the next row. When calling $stmt->fetch(), mysqli assigns it to the references in $pointers and thus to the fields in the $row object.
$pointers is an array because mysqli_stmt_bind_result expects one. Objects do not have 0..n fields but rather named values - so to assign columns based on their position using a non-associative array makes much more sense.
It does pretty much the same what mysqli::fetch_object() does.

Categories