I have been having trouble storing an array in session. I am making a shopping cart and it doesn't seem to work.
public function __construct(){
$product = array(1,2,3,4);
Session::push('cart', $product);
}
and then retrieve it in the view like this.
{{Session::get('cart')}}
However I keep getting an error like this.
htmlentities() expects parameter 1 to be string, array given
Any clues and advice on how to create a shopping cart that stores an array of items.
If you need to use the array from session as a string, you need to use Collection like this:
$product = collect([1,2,3,4]);
Session::push('cart', $product);
This will make it work when you will be using {{Session::get('cart');}} in your htmls. Be aware of Session::push because it will append always the new products in sessions. You should be using Session::put to be sure the products will be always updating.
You're storing an array in the session, and since {{ }} expects a string, you can't use {{Session::get('cart')}} to display the value.
The {{ $var }} is the same as writing echo htmlentities($var) (a very simple example).
Instead, you could do something like:
#foreach (Session::get('cart') as $product_id)
{{$product_id}}
#endforeach
If you use 'push', when initially creating the array in the session, then the array will look like this:
[
0 => [1,2,3,4]
]
Instead you should use 'put':
$products = [1,2,3,4];
$request->session()->put('cart', $products);
Any subsequent values should be pushed onto the session array:
$request->session()->push('cart', 5);
You can use .:
$product = array(1,2,3,4);
Session::put('cart.product',$product);
You can declare an array in session like
$cart = session('data', []);
$cart[] = $product;
session([ 'data' => $cart]);
return session('data', []);
you can also do it like that:
$data = collect($Array);
Session()->put('data', $data);
return view('pagename');
Related
I have a Laravel site I am modifying, but there are some parts of the PHP code I don't quite understand, which are "array objects" or "object arrays". You see, I don't even know what to call them and so can't find a tutorial or basic data on it. Below is the code that I am dealing with:
private function parseMetric($result, $view)
{
$data = collect([]);
$result->each(function($item) use ($data, $view) {
if (isset($item->metric->{$view})) {
$data->push((object)[
'label' => $item->metric->{$view},
'value' => $item->metric->count
]);
}
});
...
From what I can tell, this creates an object out of $result. If I json_encode this and echo it out I get this:
[{"label":"1k-25k","value":14229},
{"label":"1mm+","value":1281},
{"label":"25k-50k","value":398},
{"label":"50k-75k","value":493},
{"label":"75k-100k","value":3848},
{"label":"100k-150k","value":9921},
{"label":"150k-200k","value":4949},
{"label":"200k-250k","value":3883},
{"label":"250k-300k","value":2685},
{"label":"300k-350k","value":2744},
{"label":"350k-500k","value":4526},
{"label":"500k-1mm","value":8690}]
Now this is obviously an array of arrays... or is it? Is it an array of objects? Or is it an object containing arrays? But the most important question is, how do I access and move or change the individual objects/arrays in this object? For example, I want to take the second object/array, which is:
{"label":"1mm+","value":1281}
and move it to the end. How do I do that? How do I find it? I used the following piece of code to find it which is pretty clunky:
$pos = strpos(json_encode($result), '1mm+');
if($pos){
Log::debug('Enrich 73, I found it!!!!!!!!!!!!!!!!!!!!!!!!!!!');
}
And once I find it, how do I move that array/object to the end of the whole object?
And finally, where can I find some kind of tutorial, or documentation, that describes this construct and how to work with it?
There is no need to json_encode the data. Since the data is an instance of Laravel Collection, you can manipulate it like so
$item = $data->firstWhere('label', '1mm+'); // get the item
$data = $data->filter(fn($value, $key) => $value->label !== '1mm+') // remove $item from $data
->push($item); // move $item to the end of data
Acording to Laravel documnentation for Collections, you can try something like this :
To find index of element with name = "1mm+" :
$index = $datas->search(function ($item, $key) {
return $item['name'] == "1mm+";
});
to get an element at a given index :
$element = $datas->get($index);
to Move element at index 3 to the end :
$index = 3
$elementToMove = $data->splice($index, 1);
$datas->push($elementToMove);
Here is a link to the document used : https://laravel.com/docs/8.x/collections
Iam working on a laravel project which stores values to a DB entry in loop on meeting certain conditions.
This first creates an array if the entry is for the first time and adds a value to it. Henceforth, it recalls the array and keeps adding values to it.
if(is_null($lead->shown_to)) {
$a = array();
array_push($a, "lead 1");
$lead->shown_to = serialize($cart);
$lead->save();
} else {
$a=unserialize($lead->shown_to);
array_push($a, "lead 2");
$lead->shown_to = serialize($a);
$lead->save();
}
To be able to create an array and add distinct elements to it repeatedly.
Is there a way to first check if the element exists in it or not. If it does, just move ahead, else add it?
Thanks in advance.
There're a couple of methods you can use.
You can first look for the value on the DB if exists using a column from the database like:
$result = Model::where( 'column', 'value' );
if ( $result ) {
// update already exists
} else {
// create one
}
// Retrieve flight by name, or create it if it doesn't exist...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
// Retrieve by name, or instantiate...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
Also it depends what you are looking for as firstOrCreate persists the value into the DB where firstOrNew just creates a new instance where you need to call save()
to check a value exists in an array you can use array_search(). this will return the value if exists. if not it returns false.
if(!array_search('lead 2', $a)) {
// array does't has 'lead 2' so,
array_push('lead 2', $a);
}
In Laravel I would take advantage of the Collections because they have a lot of helpful methods to work with.
I would do something like this:
OPTION 1
//Depending on the value of $lead->show, initialize the cart variable with the serialization of the attribute or and empty array and transform it to a collection.
$cart = collect($lead->shown_to ? unserialize($lead->shown_to) : []);
//Ask if the collection doesn't have the given value. If so, added it.
if (!$cart->contains($your_value)) {
$cart->push($your_value);
}
//Convert to array, serialize and store
$lead->shown_to = serialize($cart->toArray());
$lead->save();
OPTION 2
//Depending on the value of $lead->show, initialize the cart variable with the serialization of the attribute or and empty array and transform it to a collection.
$cart = collect($lead->shown_to ? unserialize($lead->shown_to) : []);
//Always push the value
$cart->push($your_value);
//Get the unique values, convert to an array, serialize and store
$lead->shown_to = serialize($cart->unique()->toArray());
$lead->save();
You can get more creative using the collections and they read better on Laravel
I think you can use updateOrCreate, if not exists it will create now, if exists, it will update it, so you can keep assigning value to shown_to property
$lead= App\Lead::updateOrCreate(
['name' => 'Lead 1'],
['shown_to' => serialize($a)]
);
if you wan to keep the existing shown_to better to use json data, so that you can do like
$lead= App\Lead::updateOrCreate(
['name' => 'Lead 1'],
['shown_to' => json_encode(array_push(json_decode($a), $newData))]
);
I wanted to retrieve session array and put into other model But throws `
Call to a member function pluck() on array
Controller I used :
$orders = $request->session()->get('order');
$order = new Order();
$order->school_id = $orders->pluck('school_id');
$order->order_date = $orders->pluck('order_date');
$order->time_slot = $orders->pluck('time_slot');
How do i access the session data and put into other model?
Here is the response I get when i dd() the session :
array:1 [▼
0 => array:3 [▼
"school_id" => "4"
"order_date" => "11/25/2017"
"time_slot" => "10am - 8pm"
]
]
try like this,
$orders = $request->session()->get('order');
print_r($orders);
if you getting orders of school id array then you can get it by $orders['school_id']; and if you getting std object then you can retrieve it by $orders->school_id;
Use as per output of print_r(orders)
Then you can store it by
If std object ::
$order = new Order();
$order->school_id = $orders[0]->school_id;
$order->order_date = $orders[0]->order_date;
$order->time_slot = $orders[0]->time_slot;
$order->save();
If array ::
$order = new Order();
$order->school_id = $orders[0]['school_id'];
$order->order_date = $orders[0]['order_date'];
$order->time_slot = $orders[0]['time_slot'];
$order->save();
I would use the array_get helper.
https://laravel.com/docs/5.5/helpers#method-array-get
array_get($orders, 'school_id');
Additionally you can use a fallback as third parameter in case the value is not present in the session.
Session holds all data in Array and not Collection. Function pluck() can only be used for the collection.
Try doing array_get($orders, 'school_id'); as already mentioned by Marc or just $request->session()->get('order')['school_id'];
Call to a member function pluck() on array
Your $orders variable is an array so you can't use pluck. You can do $order['key'] to access their values. Or as others suggested, use the helper function array_get
it depends on how did you store it into session, so if you used push, then it will be stored as array.
anyways change your code to the following:
$orders = $request->session()-> pull('order',$defaultOrdersArrayCanBeHere);
$order = new Order();
$order->school_id = $orders['school_id'];
$order->order_date = $orders['order_date'];
$order->time_slot = $orders['time_slot'];
UPDATE:
Did you push it to session as so: session()->push('order', $order);
where:
$order = [
'school_id'=> $schoolId;
'order_date'=> $orderDate;
'time_slot'=> $timeSlot;
]
I have a multidimensional array $data on the controller side. I populate $data[$group] with any group value, between G1 - G100. I then pass the array to a view via a controller:
$this->load->view('example', $data);
On the view-side I can then access the variable, for instance $G1, $G2. The problem is that I dont know before-hand what will be passed. I can try to access my variable like this in the view:
if (isset($G1)) echo $G1;
if (isset($G2)) echo $G2;
if (isset($G3)) echo $G3;
But this becomes highly unpractical when the group variable in $data[$group] on the controller-side can have many different values.
Is there any way to check from the view beforehand what is being sent?
I don't think it is possible to know what will be passed, but you can put $data itself into an array and pass this array to the view, and in the view go through $data with a foreach:
//controller
$newdata = array(
//maybe other data
'data' => $data
);
$this->load->view('someview', $newdata);
//view
foreach($data as $key => $value){
//do whatever you like
}
How can I grab this data and increment it in Codeigniter?
$_SESSION['cart'][$_GET[id]]++;
because CI destroys the $_GET array, you can do this
$_SESSION['cart'][$this->uri->segment(3)]++;
where 3 is the URL segment of the ID. But I would look in to the shopping cart class as recommended by Malachi.
from the docs ~
$data = array(
'rowid' => 'b99ccdf16028f015540f341130b6d8ec',
'qty' => 3
);
$this->cart->update($data);
It's frowned upon, but if you really want to use the $_GET var you can always do the following:
parse_str($_SERVER['QUERY_STRING'],$_GET);
I would stick with using URI segments as shown by Ross or have the 'id' supplied as a parameter in the controller function.
maybe like this...
$cart = $this->session->userdata('cart');
$cart[$this->uri->segment(3)];
$this->input->get() is no longer messed with, so GET away.
You can do in this way.
By passing variable in your controller function, Your controller function will look like this
function my_function($id='')
{
//Your code goes here
$my_cart = $this->session->userdata('cart');
$my_data = $my_cart[$id];
}