Call to undefined method stdClass::count() in laravel - php

I trying to paginate my JSON response but got error like this
Call to undefined method stdClass::count()
My JSON response from the Laravel API by using guzzle ......
here is my controller code
public function index()
{
$response = $this->client->get('getUserIndex')->getBody();
$content = json_decode($response->getContents());
$total = $content->count();
$paginationRecord = CollectionPaginate::paginate($content, $total, '15');
return view('configuration.comuserprofiles.ComUserProfilesList', ['paginationRecord' => $paginationRecord->data]);
}

$content = json_decode($response->getContents());
$total = $content->count();
I am not entirely sure why you think the result of json_decode would have a count method? The JSON decoding always results in a generic object (stdClass) since there's no way for the PHP interpreter to know it represents an available class.
The ->count method is available on Countable implementations (such as ArrayCollection). If you expect a Countable class, then you can either have a factory to build your object from JSON or try to cast the stdClass to ArrayCollection.
Otherwise, if your JSON data is a valid array, you can try to use
$decoded = json_decode($data, true)
meaning it will decode it to an array rather than an object, which enables you to do
count($decoded)

$content is an object, not a collection or array you can use php method count with array get $total
Please Change to
public function index()
{
$response = $this->client->get('getUserIndex')->getBody();
$content = json_decode($response->getContents(),true );
$total = count($content);
$paginationRecord = CollectionPaginate::paginate($content, $total, '15');
return view('configuration.comuserprofiles.ComUserProfilesList', ['paginationRecord' => $paginationRecord->data]);
}

Related

How to make a PHP function with array of arguments

Hi I'm new with PHP usually I work with Java, how actually the right way to write an array of many arguments/parameters in this insertSQL function as I have a lot SQL objects have to be inserted. Thank you
//Store User into MySQL DB
$res = $db->insertSQL(
$data[$i]->id,
$data[$i]->location_id,
$data[$i]->section_id,
$data[$i]->inspection_date,
$data[$i]->photo_entire_path,
$data[$i]->photo_isolator_path,
$data[$i]->pole_no,
$data[$i]->pole_iron,
$data[$i]->pole_iron,
$data[$i]->pole_iron);
//Based on inserttion, create JSON response
if($res){
$b["id"] = $data[$i]->id;
$b["status"] = 'yes';
array_push($a,$b);
}else{
$b["id"] = $data[$i]->id;
$b["status"] = 'no';
array_push($a,$b);
}
Right now it looks like this
$res = $db->insertSQL(
$data[$i]->id,
$data[$i]->location_id,
$data[$i]->section_id,
$data[$i]->inspection_date,
$data[$i]->photo_entire_path,
$data[$i]->photo_isolator_path,
$data[$i]->pole_no,
$data[$i]->pole_iron,
$data[$i]->pole_concrete,
$data[$i]->pole_wood,
$data[$i]->pole_condition_broken,
$data[$i]->pole_condition_tilt,
$data[$i]->pole_condition_shift,
$data[$i]->cros_arm_twist,
$data[$i]->cross_arm_rust,
$data[$i]->cross_arm_tilt,
$data[$i]->arm_tie_repair,
$data[$i]->arm_tie_rust,
$data[$i]->arm_tie_brace,
$data[$i]->isolator_fulcrum_r_leak,
$data[$i]->isolator_fulcrum_r_broken,
$data[$i]->isolator_fulcrum_s_leak,
$data[$i]->isolator_fulcrum_s_broken,
$data[$i]->isolator_fulcrum_t_leak,
$data[$i]->isolator_fulcrum_t_broken,
$data[$i]->isolator_pull_r_leak,
$data[$i]->isolator_pull_r_broken,
$data[$i]->isolator_pull_s_leak,
$data[$i]->isolator_pull_s_broken,
$data[$i]->isolator_pull_t_leak,
$data[$i]->isolator_pull_t_broken,
$data[$i]->arrester_r_broken,
$data[$i]->arrester_s_broken,
$data[$i]->arrester_t_broken,
$data[$i]->conductor_r_buyer,
$data[$i]->conductor_r_loose,
$data[$i]->conductor_s_buyer,
$data[$i]->conductor_s_loose,
$data[$i]->conductor_t_buyer,
$data[$i]->conductor_t_loose,
$data[$i]->connector_pg_r_35mm,
$data[$i]->connector_pg_r_70mm,
$data[$i]->connector_pg_r_150mm,
$data[$i]->connector_pg_s_35mm,
$data[$i]->connector_pg_s_70mm,
$data[$i]->connector_pg_s_150mm,
$data[$i]->connector_pg_t_35mm,
$data[$i]->connector_pg_t_70mm,
$data[$i]->connector_pg_t_150mm,
$data[$i]->bending_wire_r,
$data[$i]->bending_wire_s,
$data[$i]->bending_wire_t,
$data[$i]->ultrasonic_r,
$data[$i]->ultrasonic_s,
$data[$i]->ultrasonic_t,
$data[$i]->gws_exist,
$data[$i]->gws_not_exist,
$data[$i]->tree_exist,
$data[$i]->tree_not_exist,
$data[$i]->longitude,
$data[$i]->latitude,
$data[$i]->suggestion,
$data[$i]->descr
);
If I understand you correctly, this is what your function should look like:
function insertSQL(Array $sqlData)
{
Extract the values from the $sqlData variable here.
}
Try the following solution using call_user_func_array, func_get_args, json_encode and json_decode functions (to deal with an array of arguments):
...
$encoded = json_encode($data[$i]);
$fields_arr = json_decode($encoded, true); // to get an array of object properties with values.
// Also you should, probably, check the order of fields
$fields_arr['id'] = false;
$fields_arr = array_filter($fields_arr); // for removing the 'id' field
$args = ['id' => $data[$i]->id]; // first argument
call_user_func_array(array($db, 'insetSQL'), array_merge($args, $fields_arr)); // it also may require your current Namespace in the first arg
...
// Then, the 'insetSQL' method should process the arguments in the following manner:
function insetSQL($fields = []) {
$fields = func_get_args();
$id = $fields[0];
// adjusting the rest of fields ($fields[1], $fields[2] ...)
...
}
Although, I also would suggest to pass the initial object $data[$i] right into the insetSQL method as parameter and get the needed fields for sql INSERT statement
Create a JSON object as
$named_array = array(
"longitude" => "12.2"
"latitude" => "12.2"
);
$named_array = json_encode($named_array);
This $named_array can be array of fields.
You can pass $named_array object to other function as an argument.
Then use
$named_array = json_decode($named_array)
echo $named_array->longitude
You can access any Key Value pair as $named_array->latitude

Codeigniter passing objects within views

I am loading a view from a Controller file and that View loads another view which a final one as below,
First view Call :
Controller: device.php
public function device_name(){
$data = new stdClass;
$data->device_name = "Apple";
$this->load->view('apple_device',$data);
}
Second view call :
View: In apple_device.php
$device_name->count = 123;
$this->load->view('device_counts',$device_name);
I am using object here instead of an array as a passing variable between views. But if i use array, it works fine.
And the above code throwing error as like below,
Message: Attempt to assign property of non-object
Any help would be appreciated.
Yes, you may still pass through objects, but not at the 'first level', you'll need to wrap the object you want to pass through inside an array.
public function device_name(){
$mobiles = new stdClass;
$mobiles->device_name = "Apple";
$data = array( "mobiles" => $mobiles );
$this->load->view('apple_device',$data);
}
This is because when CodeIgniter will initialize the view, it will check the contents of the second view() parameter. If it's an object - it'll cast it to an array via get_object_vars() (See github link)
protected function _ci_object_to_array($object)
{
return is_object($object) ? get_object_vars($object) : $object;
}
Which will in turn, turn your initial $data into:
$data = new stdClass;
$data->device_name = "Apple";
$example = get_object_vars( $data );
print_r( $example );
Array ( [device_name] => Apple )
Thus to avoid this, nest your object inside an array() which will avoid being converted.

Lithium: How to manually populate a DocumentSet?

How can I return data from an external source as a DocumentSet?
I set up a custom data source to interface with Amazon's Product Advertising API. To do this, I subclassed lithium\data\source\Http and redefined the read method to suit my needs as described in the documentation (http://li3.me/docs/manual/working-with-data/creating-data-sources.wiki).
However, my lithium version (0.11, last release) does not seem to have a cast method like in the example and if I create one it won't get called when I do return $this->item($model, $data, $options).
So, I made a custom item function to create the Documents by calling parent::item just like the documentation example does for cast.
Then, after the recursive calls, I end up with an array of Document objects and the final call to parent::item then gives me an empty DocumentSet object.
How should I pass the data on to create a proper DocumentSet?
Here's a minimal example of my code:
// Within class Amazon extends \lithium\data\source\Http
protected function _init() {
// Define entity classes.
$this->_classes += array(
'entity' => 'lithium\data\entity\Document',
'set' => 'lithium\data\collection\DocumentSet'
);
parent::_init();
}
public function read($query, array $options = array()) {
// Extract from query object.
$parameters = $query->export($this, array('keys' => array('conditions')));
$conditions = $parameters['conditions'];
// Code stripped to validate conditions and prepare Amazon request (that part works).
// results in a $queryString variable.
// Get response from Server.
$xml = simplexml_load_string($this->connection->get($this->_config['basePath'], $queryString));
// Stripped response validation and reformatting -> $items contains an array of SimpleXMLElement objects.
return $this->item($query->model(), $items, array('class' => 'set'));
}
public function item($model, array $data = array(), array $options = array()) {
// Recursively create Documents for arrays.
foreach($data as $key => $value) {
if(is_array($value)) {
$data[$key] = $this->item($model, $value, array('class' => 'entity'));
}
else if(is_object($value) && get_class($value) == "SimpleXMLElement") {
// Stripped code to extract data from XML object and put it in array $docData.
$data[$key] = $this->item($model, $docData, array('class' => 'entity'));
}
}
// Works perfectly for every (recursive) call with $options['class'] == 'entity' but fails for the final call with $options['class'] == 'set' (for this final call $data contains an array of Document objects).
return parent::item($model, $data, $options);
}
I would track the master branch instead of the release versions.
In your case, since you're boxing your objects manually, I would do something like:
return $this->_instance('set', compact('data'));

PHP: Return the last json object

Edit
Thanks for all the input on this, I did find error in my question so modifying now. Sorry for that.
I am trying to figure out how to return the last object in the JSON string I have rendered. The two functions I am working with:
public function revision($return = false)
{
$id = $this->input->post('galleryID');
$data = array('revision_count' => $this->revision->count_revision($id) );
if($return){
return json_encode($data);
}
else {
echo json_encode($data);
}
}
public function last_revision()
{
$allRevisions = json_decode($this->revision(),true);
return end($allRevisions);
}
The issue is that end() returns error stating that 1st parameter should be array.
Thanks for any help on this.
It is important to note here that json_decode returns an instance of stdClass by default. Try using json_decode($jsonstring, true) to return the JSON as a PHP associative array.
However, You haven't included what the $this->revision() method does. Could you possibly show that portion of the code, since that is the function you are getting a return value from?
Edit:
Alright, after we saw the right function in your code, here are a couple of things I would like to say:
You have added a $return parameter to your revision method, but you aren't using it when you need to. You should change $this->revision() to $this->revision(true) in your last_revision method.
If you're going to return data from the revision() method, there's not much of a point in json_encodeing it, just to json_decode the result. Just pass back the raw data array.
Once you have changed both of these things, this should work:
$allRevisions = $this->revision(true); return end($allRevisions['revision_count']);
You can change the edit_function() to:
public function edit_revision($return = false)
{
$galleryID = $this->input->post('galleryID');
$revisionID = $this->input->post('revisionID');
$data = array('revision_images' => $this->revision->get($galleryID, $revisionID) );
if($return)
return json_encode($data);
else
echo json_encode($data);
}
and then:
public function last_revision(true)
{
$allRevisions = json_decode($this->revision());
return end($allRevisions);
}
Maybe you need convert that json output to an php array (json_decode() function), then you could get the last item with array_pop() function:
https://php.net/array_pop

Cannot use object of type stdClass as array?

I get a strange error using json_decode(). It decode correctly the data (I saw it using print_r), but when I try to access to info inside the array I get:
Fatal error: Cannot use object of type stdClass as array in
C:\Users\Dail\software\abs.php on line 108
I only tried to do: $result['context'] where $result has the data returned by json_decode()
How can I read values inside this array?
Use the second parameter of json_decode to make it return an array:
$result = json_decode($data, true);
The function json_decode() returns an object by default.
You can access the data like this:
var_dump($result->context);
If you have identifiers like from-date (the hyphen would cause a PHP error when using the above method) you have to write:
var_dump($result->{'from-date'});
If you want an array you can do something like this:
$result = json_decode($json, true);
Or cast the object to an array:
$result = (array) json_decode($json);
You must access it using -> since its an object.
Change your code from:
$result['context'];
To:
$result->context;
Use true as the second parameter to json_decode. This will decode the json into an associative array instead of stdObject instances:
$my_array = json_decode($my_json, true);
See the documentation for more details.
Have same problem today, solved like this:
If you call json_decode($somestring) you will get an Object and you need to access like $object->key , but if u call json_decode($somestring, true) you will get an dictionary and can access like $array['key']
It's not an array, it's an object of type stdClass.
You can access it like this:
echo $oResult->context;
More info here: What is stdClass in PHP?
As the Php Manual say,
print_r — Prints human-readable information about a variable
When we use json_decode();, we get an object of type stdClass as return type.
The arguments, which are to be passed inside of print_r() should either be an array or a string. Hence, we cannot pass an object inside of print_r(). I found 2 ways to deal with this.
Cast the object to array.
This can be achieved as follows.
$a = (array)$object;
By accessing the key of the Object
As mentioned earlier, when you use json_decode(); function, it returns an Object of stdClass. you can access the elements of the object with the help of -> Operator.
$value = $object->key;
One, can also use multiple keys to extract the sub elements incase if the object has nested arrays.
$value = $object->key1->key2->key3...;
Their are other options to print_r() as well, like var_dump(); and var_export();
P.S : Also, If you set the second parameter of the json_decode(); to true, it will automatically convert the object to an array();
Here are some references:
http://php.net/manual/en/function.print-r.php
http://php.net/manual/en/function.var-dump.php
http://php.net/manual/en/function.var-export.php
Try something like this one!
Instead of getting the context like:(this works for getting array index's)
$result['context']
try (this work for getting objects)
$result->context
Other Example is: (if $result has multiple data values)
Array
(
[0] => stdClass Object
(
[id] => 15
[name] => 1 Pc Meal
[context] => 5
[restaurant_id] => 2
[items] =>
[details] => 1 Thigh (or 2 Drums) along with Taters
[nutrition_fact] => {"":""}
[servings] => menu
[availability] => 1
[has_discount] => {"menu":0}
[price] => {"menu":"8.03"}
[discounted_price] => {"menu":""}
[thumbnail] => YPenWSkFZm2BrJT4637o.jpg
[slug] => 1-pc-meal
[created_at] => 1612290600
[updated_at] => 1612463400
)
)
Then try this:
foreach($result as $results)
{
$results->context;
}
To get an array as result from a json string you should set second param as boolean true.
$result = json_decode($json_string, true);
$context = $result['context'];
Otherwise $result will be an std object. but you can access values as object.
$result = json_decode($json_string);
$context = $result->context;
Sometimes when working with API you simply want to keep an object an object. To access the object that has nested objects you could do the following:
We will assume when you print_r the object you might see this:
print_r($response);
stdClass object
(
[status] => success
[message] => Some message from the data
[0] => stdClass object
(
[first] => Robert
[last] => Saylor
[title] => Symfony Developer
)
[1] => stdClass object
(
[country] => USA
)
)
To access the first part of the object:
print $response->{'status'};
And that would output "success"
Now let's key the other parts:
$first = $response->{0}->{'first'};
print "First name: {$first}<br>";
The expected output would be "Robert" with a line break.
You can also re-assign part of the object to another object.
$contact = $response->{0};
print "First Name: " . $contact->{'first'} . "<br>";
The expected output would be "Robert" with a line break.
To access the next key "1" the process is the same.
print "Country: " . $response->{1}->{'country'} . "<br>";
The expected output would be "USA"
Hopefully this will help you understand objects and why we want to keep an object an object. You should not need to convert an object to an array to access its properties.
You can convert stdClass object to array like:
$array = (array)$stdClass;
stdClsss to array
When you try to access it as $result['context'], you treating it as an array, the error it's telling you that you are actually dealing with an object, then you should access it as $result->context
Here is the function signature:
mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )
When param is false, which is default, it will return an appropriate php type. You fetch the value of that type using object.method paradigm.
When param is true, it will return associative arrays.
It will return NULL on error.
If you want to fetch value through array, set assoc to true.
I got this error out of the blue because my facebook login suddently stopped working (I had also changed hosts) and throwed this error. The fix is really easy
The issue was in this code
$response = (new FacebookRequest(
FacebookSession::newAppSession($this->appId, $this->appSecret),
'GET',
'/oauth/access_token',
$params
))->execute()->getResponse(true);
if (isset($response['access_token'])) { <---- this line gave error
return new FacebookSession($response['access_token']);
}
Basically isset() function expect an array but instead it find an object. The simple solution is to convert PHP object to array using (array) quantifier. The following is the fixed code.
$response = (array) (new FacebookRequest(
FacebookSession::newAppSession($this->appId, $this->appSecret),
'GET',
'/oauth/access_token',
$params
))->execute()->getResponse(true);
Note the use off array() quantifier in first line.
instead of using the brackets use the object operator for example my array based on database object is created like this in a class called DB:
class DB {
private static $_instance = null;
private $_pdo,
$_query,
$_error = false,
$_results,
$_count = 0;
private function __construct() {
try{
$this->_pdo = new PDO('mysql:host=' . Config::get('mysql/host') .';dbname=' . Config::get('mysql/db') , Config::get('mysql/username') ,Config::get('mysql/password') );
} catch(PDOException $e) {
$this->_error = true;
$newsMessage = 'Sorry. Database is off line';
$pagetitle = 'Teknikal Tim - Database Error';
$pagedescription = 'Teknikal Tim Database Error page';
include_once 'dbdown.html.php';
exit;
}
$headerinc = 'header.html.php';
}
public static function getInstance() {
if(!isset(self::$_instance)) {
self::$_instance = new DB();
}
return self::$_instance;
}
public function query($sql, $params = array()) {
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)) {
$x = 1;
if(count($params)) {
foreach($params as $param){
$this->_query->bindValue($x, $param);
$x++;
}
}
}
if($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
}
else{
$this->_error = true;
}
return $this;
}
public function action($action, $table, $where = array()) {
if(count($where) ===3) {
$operators = array('=', '>', '<', '>=', '<=');
$field = $where[0];
$operator = $where[1];
$value = $where[2];
if(in_array($operator, $operators)) {
$sql = "{$action} FROM {$table} WHERE {$field} = ?";
if(!$this->query($sql, array($value))->error()) {
return $this;
}
}
}
return false;
}
public function get($table, $where) {
return $this->action('SELECT *', $table, $where);
public function results() {
return $this->_results;
}
public function first() {
return $this->_results[0];
}
public function count() {
return $this->_count;
}
}
to access the information I use this code on the controller script:
<?php
$pagetitle = 'Teknikal Tim - Service Call Reservation';
$pagedescription = 'Teknikal Tim Sevice Call Reservation Page';
require_once $_SERVER['DOCUMENT_ROOT'] .'/core/init.php';
$newsMessage = 'temp message';
$servicecallsdb = DB::getInstance()->get('tt_service_calls', array('UserID',
'=','$_SESSION['UserID']));
if(!$servicecallsdb) {
// $servicecalls[] = array('ID'=>'','ServiceCallDescription'=>'No Service Calls');
} else {
$servicecalls = $servicecallsdb->results();
}
include 'servicecalls.html.php';
?>
then to display the information I check to see if servicecalls has been set and has a count greater than 0 remember it's not an array I am referencing so I access the records with the object operator "->" like this:
<?php include $_SERVER['DOCUMENT_ROOT'] .'/includes/header.html.php';?>
<!--Main content-->
<div id="mainholder"> <!-- div so that page footer can have a minum height from the
header -->
<h1><?php if(isset($pagetitle)) htmlout($pagetitle);?></h1>
<br>
<br>
<article>
<h2></h2>
</article>
<?php
if (isset($servicecalls)) {
if (count ($servicecalls) > 0){
foreach ($servicecalls as $servicecall) {
echo '<a href="/servicecalls/?servicecall=' .$servicecall->ID .'">'
.$servicecall->ServiceCallDescription .'</a>';
}
}else echo 'No service Calls';
}
?>
Raise New Service Call
</div> <!-- Main content end-->
<?php include $_SERVER['DOCUMENT_ROOT'] .'/includes/footer.html.php'; ?>
It is most likely when it tries to access the data with the generic bracket array accessor and not an object operator. Always ensure the variable type is before accessing the data.
While decoding the JSON, the response will be generated as stdObject instances
Rather than calling $result['context'];, access it by $result->context;
If it needs to call as an array itself, decode the JSON by passing the second parameter as true like
json_decode($jsonData, true);
Change it for
$results->fetch_array()

Categories