Laravel - How to convert Stdclass object to Array - laravel

I'm facing this problem when use database in Laravel. How can i convert that to Array the most simpletest?
$data = DB::table('users')->get();

Please try this. this will return array of objects.
$result = json_decode(json_encode($data, true));
*Updated
if you want to convert all nested properties to the array, try this.
$result = json_decode(json_encode($data, true), true);

get() will return a collection. If you want to get an array of objects, use the toArray() method:
$data->toArray();
If you want to convert every object to an array too, do this:
$data->map(function($i) {
return (array)$i;
})->toArray();

I usually run into this problem when I use DB::select and manually write my sql:
$sql = 'SELECT *
FROM ba_pics ba
INNER JOIN pages pgs
ON ba.service_page_id = pgs.id';
$baPics = DB::select($sql);
$baPics = json_decode(json_encode($baPics, true), true);
return view('beforeAndAfter',['baPics'=>$baPics, 'lodata'=>'no lodata yet']);
Here is another way using PHP's array_map function:
$sql = 'SELECT *
FROM ba_pics ba
INNER JOIN pages pgs
ON ba.service_page_id = pgs.id';
$baPics = DB::select($sql);
$baPics = array_map(function($i) {
return (array)$i;
}, $baPics);
return view('beforeAndAfter',['baPics'=>$baPics, 'lodata'=>'no lodata yet']);

Related

How to add object to existing Laravel Query?

What I want to do is add an object to the existing query.
This is my work in progress right now:
$users = ModelUser::where('date_created', $date)->get();
foreach($users as $user){
$obj = ['test1'=> 'val1','test2' => 'val2','test3'=> 'val3',];
$users['items'] = $obj;
}
return $users;
what I'm hoping is a result is like this.
{"username":'Username1', "Fname":'fname1', "items":['test1' = 'val1','test3' = 'val3','test3' = 'val3']
"username":'Username2', "Fname":'fname2', "items":['test1' = 'val1','test3' = 'val3','test3' = 'val3']
"username":'Username3', "Fname":'fname3', "items":['test1' = 'val1','test3' = 'val3','test3' = 'val3']
"username":'Username4', "Fname":'fname4', "items":['test1' = 'val1','test3' = 'val3','test3' = 'val3']
}
Where the items are like in a sub object.
Convert it into a collection and push into it
https://laravel.com/docs/9.x/collections#method-push
Just to understand a bit more, does the "items" element you want to add to the user object have any relationship at the database level?
If so, it would be better to define a relationship within the ModelUser https://laravel.com/docs/9.x/eloquent-relationships#defining-relationships
In case not, I see you're using a $user as an array, but actually $user is a ModelUser element.
So a trick, definitely not recommended, would be:
$user->items = $obj;
You can use laravel map as
$users = ModelUser::where('date_created', $date)->get();
will return a collection. So your expected code will be something like the following
$users = $users
->map(function ($user) use ($obj) {
return $user->items = $obj;
})
);

How I can paginate DB::select(...) result and get links() method?

I have a big and difficult SQL query. It works fine for me. And I have the following code in the controller:
public function index(OpenRegDepDataReportInterface $openRegDepDataReport, Request $request): Renderable
{
$applications = $openRegDepDataReport->getReport($advertisers, $category);
return view('applications.index', compact('applications'));
}
So, the method getReport gives me a result of DB::select('<here is my big diffecult SQL>'), and, as well known it's an array.
But as you can see I'm trying to pass the result on a view. And, of course, I would like to call $applications->links() in the view, like for eloquent collection. Which is proper and faster way to do that?
doc
To display pagination at the table, you must call the select and then the pagination method.
in Controller:
$test = DB::table('users')->select('id')->paginate(10);
in View:
$test->links();
So based on the documentation if your $applications returns a Query Builder result, then just append ->paginate(10); to it.
https://laravel.com/docs/master/pagination#paginating-query-builder-results
$applications = $openRegDepDataReport->getReport($advertisers, $category)->paginate(10);
Simple answer, use paginate() method:
$basicQuery = DB::select(DB::raw("<here is the big diffcult SQL query>"));
However, paginate() works only on collections, and since you have an array of objects, you need to turn it into a collection first, using the forPage() method:
The forPage method returns a new collection containing the items that would be present on a given page number. The method accepts the page number as its first argument and the number of items to show per page as its second argument:
$collection = collect($basicQuery);
$chunk = $collection->forPage(2, 3);
$chunk->all();
Complicated answer: build a paginator instance yourself:
$perPage = 10;
$page = $request->input("page", 1);
$skip = $page * $perPage;
if($take < 1) { $take = 1; }
if($skip < 0) { $skip = 0; }
$basicQuery = DB::select(DB::raw("<here is the big diffcult SQL query>"));
$totalCount = $basicQuery->count();
$results = $basicQuery
->take($perPage)
->skip($skip)
->get();
$paginator = new \Illuminate\Pagination\LengthAwarePaginator($results, $totalCount, $take, $page);
return $paginator;
I would recommend using the paginate() method.
You can read more about Laravel's pagination.

Laravel fetch raw query result

I don't want laravel to format my query result to an array or object ..etc. All I want, is to run the result set from database and then I will manually do the fetch myself in my custom code.
At the moment, I ran my select query and get my result in an array. The reasons for that, because the result is huge and I want to stream it directly to API.
$result = self::$db->select('select * from customer');
How can I tell laravel, to return my query result set without any format at all?
You can use DB:Raw like:
$results = DB::table('users')->select(DB::raw("*"))->get()
Or
$results = DB::select('select * from users where id = ?', [1]);
These two will return a neat object without any casts or relations etc. You can also make any object or array your API need by simple eloquent models by the way. Please explain more about data type you wanna extract from model query.
You must be use ->toSql() or ->dd()
Exapmle
Customer::toSql(); // select * from `customer`
if you want some condition
$query = Customer::where(`some conditions`);
$sql = $query->toSql();
$bindings = $query->getBindings();
$sql = str_replace('?', '%s', $sql);
$sql = sprintf($sql, ...$bindings);
Thanks everyone, I end up writing a raw function to query the data I want from database.
public static function dataStreamJSON($stmt, $headers)
{
return Response::stream(function() use ($stmt){
$conn = self::getConnection();
$result = sqlsrv_query($conn, "exec $stmt");
echo '
{
"Customers": {
"Customer": [';
$counter = 0;
while($customer = sqlsrv_fetch_object($result)) {
if($counter !== 0){
echo ",";
}
$counter++;
$row = [
'Firstname' => $customer->Firstname,
'Lastname' => $customer->Lastname,
...
];
echo json_encode($row);
unset($row);
unset($customer);
}
echo ']
}
}';
#sqlsrv_free_stmt($result);
#sqlsrv_close($conn);
}, 200, $headers);
}
The purpose of this code is to stream the data out to JSON format on browser without store the data in any variable, which will caused “out of memory” error.
I managed to stream 700MB of JSON data to the browser without any error. With this code, you will never run into “out of memory” error.
Best way to test this, is to use CURL to access your API and download the data to a JSON file. If you open on browser, it will freeze your screen because browser can't handle large data.
You can use toArray() or toJson() methods like below:
$array = Customer::all()->toArray();
$json = Customer::all()->toJson();
echo '<pre>';
print_r($array);
print_r($json);
If you want to run raw SQL Queries, you can do as below
$users = DB::select('select * from users where 1');
echo '<pre>';
print_r($users);
You can use
1) query builder way:-
DB::table('your_table_name)->select('your_col_names')->get();
eg:- DB::table('shop')->select('product_id','product_name')->get();
2) use laravel Raw
$orders = DB::table('orders')->selectRaw('price * ? as price_with_tax', [1.0825])->get();
3) for select raw
$product_count = DB::table('product')->select(DB::raw('count(*) as total_product_count'))->where('status',1)->get();

Laravel5 Eloquent custom method return array

I have a static method in my User model which counts something, i am using a raw statement:
static function countOrders($userId)
{
$sql = "SOME CUSTOM-COMPLICATED QUERY";
$result = \DB::select( \DB::raw( $sql ) );
return $result; // <-- toArray() ? returns Exception!
}
Somewhere in my controller:
$orders = User::countOrders(*USER-ID*);
How can I get an array with records as arrays and not objects without modifying the global configuration for the FETCH method?
You don't need to run toArray().
When executing raw queries select returns array, it's stated in the docs:
The select method will always return an array of results.
static function countOrders($userId)
{
$sql = "SOME CUSTOM-COMPLICATED QUERY";
$result = \DB::select( \DB::raw( $sql ) );
return $result;
}

Getting an array of blocks with the same id magento

$id = 'unique_id_block';
$cmsBlockModel = Mage::getResourceModel('cms/block');
$block = Mage::getModel('cms/block');
$cmsBlockModel->load($block, $id);
I have the code above to return an a block object with the id called unique_id_block .
How is this possible to this to return an array of blocks because I may have more than 1 block with the same ID but with different store views.
You can get all blocks with the same identifier using a collection...
$id = 'unique_id_block';
$blockCollection = Mage::getModel('cms/block')->getCollection()
->addFieldToFilter('identifier', $id);
You can then iterate over this collection as you would do an array:
foreach ($blockCollection as $block) {
//...
}
Since your question asks to have these as an array though, you can also convert the collection to an array and grab its items as in the following:
$id = 'unique_id_block';
$blockCollection = Mage::getModel('cms/block')->getCollection()
->addFieldToFilter('identifier', $id)
->toArray();
$blocks = $blockCollection['items'];
But unless there is a good reason for this, i would stick with the first example.

Resources