storing array in a sql database - php

I started getting into arrays and don't quite get it to work well. I'm used to work with explode/implode functions but I though arrays would make my life easier in this part of the code. Here is the function called:
function save_event($event_items = NULL) {
include 'connect.php';
$now = date("Y-m-d H:i:s");
$sqla = "
INSERT INTO `event`(`event_items`, `event_entered`)
VALUES ('$event_items','$now')";
$resulta = mysqli_query($link, $sqla);
if(!$resulta)
{
echo '<br/>An error occurred while inserting your data. Please try again later.<br/>';
}
else
{ echo 'this is the variable to be stored:<br/>';
print_r($event_items);
$sql = "SELECT * FROM `event` WHERE event_entered = '".$now."'";
$result = mysqli_query($link, $sql);
if($result)
{ while($row = mysqli_fetch_assoc($result))
{ echo '<br/></br>This is the value of the database:<br/>';
print_r ($row['event_items']);
}
}
}
}
This function prints:
this is the variable to be stored:
Array( [0] => Array ( [item] => Powered Speaker [note] => [quantity] => 2 [price] => 200.00 [category] => Audio ) [1] => Array ( [item] => Wireless Microphone [note] => Lavalier [quantity] => 3 [price] => 175.00 [category] => Audio ))
This is the value of the database:
Array
In phpMyAdmin, all I see in the column event_items is the word Array.
Additional info:
I have a table called Groups, each group will have one or multiple orders (another table called Order) and each order will have also one or multiple events (another table). Lastly, each event will have one or multiple items (each item with its corresponding price, quantity, note and category), which are stored in one (or many) columns in the Event table.

Don't try to store an array in one field. You should store each item in the array as it's own row in a related table.

You are trying to insert multiple values in a single database record, this is not impossible but it's also not recommended in general.
The main reason someone would do this would be for optimization, which is not at all something you should worry about for now.
What you really want to do is review your database schema, if you wish to store an array of value, you need to create a new row (record) for each of those. This might necessitate the creation of another table, depending on what you want to do.

You could serialize your array with the serialize() function.
Example:
serialize($event_items);
Generates a storable representation of a value.
This is useful for storing or passing PHP values around without losing
their type and structure.
http://php.net/manual/en/function.serialize.php

Related

Array to string conversion error in Code Igniter when inserting array of data into table in database

I'm trying to insert an array of data into a table in database but an error said Array to string conversion error
This is the post function in my controller, first i post an array of data. The values of the array will be the names, and numbers, they are not id. The id is only kodejdwl. This will be pass to my model
function index_post() {
$data = array(
'kodejdwl' => $this->post('kodejdwl'),
'tahun_akad' => $this->post('kode_tahun_akad'),
'semester' => $this->post('semester'),
'mk' => $this->post('mk'),
'ruangan' => $this->post('ruangan'),
'nama_dosen' => $this->post('nama_dosen'),
'namakelas' => $this->post('nama_kelas'),
'jam_mulai' => $this->post('jam_mulai'),
'jam_selesai' => $this->post('jam_selesai'),
);
}
After the data from above code is passed to the model. I created some new variables which are the id of each the name of the value in the array data. e.g if the value of data['mk'] is Website then the id will be 1 and that id will be stored in variable $kodemk and i do it to each value in the data. Then i created new_data which stores array of the id's which i previously made. Then i insert that array into one table in my database. I thought it would be fine but it said Array to string conversion error. What should i do so i could insert that array into the table in my database?
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->result();
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->result();
$this->db->flush_cache();
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->result();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->result();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->result();
$this->db->flush_cache();
$this->db->select('kode_jam');
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->result();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id,
'matakuliah_kodemk' => $kode_mk,
'ruangan_namaruang' => $ruangan,
'staff_nip' => $nip_dosen,
'kelas_kodeklas' => $kodeklas,
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
You probably want to use row() instead of result() because it'll contain only one result that you want. If you want to use result() and store multiple values then you'll have to use implode to concatenate them and store it as a string.
I've written a possible solution for your problem; Some things were missing, so I've mentioned them in the comments. See if this helps you.
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->row(); // use row here
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->row();
$this->db->flush_cache();
// remove your_ruangan_column with your desired column name
$this->db->select('your_ruangan_column');
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->row();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->row();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->row();
$this->db->flush_cache();
// Not sure where this ↓↓ is being used but you can use it the same way as others
$this->db->select('kode_jam');
// duplicate variable name here ↓↓ (fix this)
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->row();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id->thn_akad_id, // {$tahunakad_id} consists an object with the key {thn_akad_id}-- table_column_name
'matakuliah_kodemk' => $kode_mk->kodemk, // ...
'ruangan_namaruang' => $ruangan->your_ruangan_column, // ...
'staff_nip' => $nip_dosen->nip, // ...
'kelas_kodeklas' => $kodeklas->kodeklas // ...
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
Your are making a total of 7 separate trips to the database. Best practice recommends that you always minimize your trips to the database for best performance. The truth is that your task can be performed in a single trip to the database so long as you set up the correct INSERT query with SELECT subqueries.
I don't know what your non-English words are, so I will use generalized terms in my demo (I've tested this successfully in my own CI project). I am also going to reduce the total subqueries to 3 to reduce the redundance in my snippet.
$value1 = $this->db->select('columnA')->where('cond1', $val1)->get_compiled_select('childTableA');
$value2 = $this->db->select('columnB')->where('cond2', $val2)->get_compiled_select('childTableB');
$value3 = $this->db->select('columnC')->where('cond3', $val3)->get_compiled_select('childTableC');
return (int)$this->$db->query(
"INSERT INTO parentTable
(column1, column2, column1)
VALUES (
($value1),
($value2),
($value3)
)"
);
// to mirror your affected rows return... 1 will be returned on successful insert, or 0 on failure
Granted this isn't using the ActiveRecord technique to form the complete INSERT query, but this is because CI doesn't allow subqueries in the VALUES portion (say, if you were to use the set() method). I am guessing this is because different databases use differing syntax to form these kinds of INSERTs -- I don't know.
The bottom line is, so long as you are fetching a single column value from a single row on each of these sub-SELECTs, this single query will run faster and with far less code bloat than running N number of individual queries. Because all of the variables involved are injected into the sql string using get_compiled_select() the stability/security integrity should be the same.

MySQL & PHP - Looping a query AND "mapping" the results of each loop to a unique array WITHOUT "MySQL" functions

I'll note that this is a very special case, hence the question to begin with. Under normal circumstances, such a function would be simple:
I have an array named $post_id, which contains 5 values
(Each numerical)
In order to print each value in the array, I use the following loop:
.
for ($i = 0; $i < $num; $i++)
{
echo $post_id[$i] . ' ';
}
...Which prints the following: 49, 48, 47, 46, 43
3. In my database, I have a table that looks like this:
post_categories
_____________________
post_id | category
__________|__________
43 | puppies
43 | trucks
46 | sports
46 | rio
46 | dolphins
49 | fifa
4. So, using the data in the array $post_id, I'd like to loop a database query to retrieve each value in the category column from the post_categories table, and place them into uniquely named arrays based on the "post id", so that something like...
echo $post_id_49[0] . ' ', $post_id_46[1];
...Would print "fifa rio", assuming you use the above table.
An example of such a query:
//Note - This is "false" markup, you'll find out why below
for ($i = 0; $i < $num; $i++)
{
$query = "SELECT category FROM post_categories WHERE post_id = $post_id[$i]";
fakeMarkup_executeQuery($query);
}
Why is this a "special" case? For the same reason the above query is "false".
To elaborate, I'm working inside of a software package that doesn't allow for "normal" queries so to say, it uses it's own query markup so that the same code can work with multiple database types, leaving it up to the user to specify their database type which leaves the program to interpret the query according to the type of database. It does, however, allow the query to be stored in the same "form" that all queries are, like "$result = *query here*" (With the only difference being that it executes itself).
For that reason, functions such as mysql_fetch_array (Or any MySQL/MySQLi function akin to that) cannot, and will not work. The software does not provide any form of built in alternatives either, effectively leaving the user to invent their own methods to achieve the same results. I know, pretty lame.
So, this is where I'm stuck. As you'd expect, all and any information you find on the Internet assumes you can use these MySQL & MySQLi functions. What I need, is an alternative method to grab one array from the results of a looped query per loop. I simply cannot come to any conclusion that actually works.
tl;dr I need to be able to (1) loop a query, (2) get the output from each loop as it's own array with it's own name, and (3), do so without the use of functions like mysql_fetch_array. The query itself does not actually matter, so don't focus on that. I know what do with the query.
I understand this is horrifically confusing, long, and complicated. I've been trudging through this mess for days - Close to the point of "cheating" and storing the data I'm trying to get here as raw code in the database. Bad practice, but sure as heck a lot easier on my aching mind.
I salute any brave soul who attempts to unravel this mess, good luck. If this is genuinely impossible, let me know so that I can send the software devs an angry letter. All I can guess is that they never considered that a case like mine would come up. Maybe this is much more simple then I make it to be, but regardless, I personally cannot come to an logical conclusion.
Additional note: I had to rewrite this twice due to some un explained error eliminating it. For the sake of my own sanity, I'm going to take a break after posting, so I may not be able to answer any follow up questions right away. Refer to the tl;dr for the simplest explanation of my need.
Sure you can do this , here ( assuming $post_ids is an array of post_id that you stated you had in the OP ), can I then assume that I could get category in a similar array with a similar query?
I don't see why you couldn't simply do this.
$post_id = array(49, 48, 47, 46, 43);
$result = array();
foreach($post_id as $id)
{
//without knowing the data returned i cant write exact code, what is returned?
$query = "SELECT category FROM post_categories WHERE post_id = $id";
$cats = fakeMarkup_executeQuery($query);
if(!empty($cats)) {
if(!isset($result[$id])){
$result[$id] = array();
}
foreach( $cats as $cat ){
$result[$id][] => $cat;
}
}
}
Output should be.
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)
Ok, assuming you can run a function (we'll call it find select) that accepts your query / ID and returns an array (list of rows) of associative arrays of column names to values (row), try this...
$post_categories = [];
foreach ($post_id as $id) {
$rows = select("SOME QUERY WHERE post_id = $id");
/*
for example, for $id = 46
$rows = [
['category' => 'sports'],
['category' => 'rio'],
['category' => 'dolphins']
];
*/
if ($rows) { // check for empty / no records found
$post_categories[$id] = array_map(function($row) {
return $row['category'];
}, $rows);
}
}
This will result in something like the following array...
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)

php & mysql: most efficient method to check large array against database

I have a large set of data stored in a multi-dimensional array. An example structure is as below:
Array
(
[1] => Array
(
[0] => motomummy.com
[1] => 1921
[2] => 473
)
[4] => Array
(
[0] => kneedraggers.com
[1] => 3051
[2] => 5067
)
)
I also have a table in a mysql database that currently contains ~80K domain names. This list will grow monthly by possibly ~10K+ domain names. The goal is to compare Array[][0] (the domain name) against the mysql database and return an array with preserved values (but key preservation is not important) that only contains unique values.
Please note, that I only want to compare the first index alone, NOT the entire array.
The initial multi-dimensional array is assumed to be enormous in size (more than likely anywhere from 100k to 10 million results). What is the best way to get data back that is not contained in the database?
What I am doing now is simply storing to an array, the complete list of domains from the database, then using the following function, comparing each value in the initial array against the database array. This is horribly slow and inefficient obviously.
// get result of custom comparison function
$clean = array_filter($INITIAL_LIST, function($elem) {
$wordOkay = true;
// check every word in "filter from database" list, store it only if not in list
foreach ($this->domains as $domain) {
if (stripos($elem[0], $domain) !== false) {
$wordOkay = false;
break;
}
}
return $wordOkay;
});
Some pseudo code or even actual code would be very helpful at this point.
Use the DBMS! It was made for stuff like that.
Create a temporary table temp { id (fill with array index); url (filled with url)}
Fill it with your array's data
Ideally create an index on temp.url
Query the database:
SELECT * FROM `temp` LEFT JOIN `urls`
WHERE urls.url = temp.url AND urls.url IS NULL;
(the table urls is your existing data)

PHP Make a multidimensional array from one mysql Row's columns?

I have the following mysql db row.
id | user_id | title_1|desc_1|link_1|title_2|desc_2|link_2|
and so on up to 10
from this one row I want to remove id and user id and have the resulting multidimensional array.
the main issue is iterarating over the associative array that is returned by my query and splitting it up into arrays of 3.
Array = (
[0] = array (
[tite_1] => 'sometitle'
[desc_1] => 'description'
[link_1] => 'a link'
)
[1] = array (
[tite_2] => 'sometitle'
[desc_2] => 'description'
[link_2] => 'a link'
)
and so on how can I achieve this I am stumped!!?
You probably want to structure your table into two tables like this:
parent(id, user_id, more_fields, whatever_you_need_here)
child(parent_id, title, desc, link)
Now it'll be very easy to get the data that you want to have.
SELECT title, desc, link FROM child WHERE parent_id = 12;
Of course, parent and child should be named appropriately, e.g. user and links.
The correct answer would be to redesign your database to use 3rd normal form. You should probably drop everything and read up on database normalization before you do anything further.
A proper design would be something like:
CREATE TABLE user_has_links (
id INT PRIMARY KEY,
user_id INT,
title TEXT,
description TEXT,
link TEXT
)
To store multiple links per user, you would simply create a new row in this table per link.
The real solution here is to fix your database to normalize these columns into other tables. However, if you are not in a position to fix your database, this code will do the job:
// $output will hold your full result set
$output = array();
while ($row = mysql_fetch_assoc($result)) {
// For each row returned, add a new array to $output
$output[] = array(
// The new array consists of 10 sub-arrays with the correct
// keys and values
array (
"title"=>$row['title1'],
"desc"=>$row['desc1'],
"link"=>$row['link1']
),
array (
"title"=>$row['title2'],
"desc"=>$row['desc2'],
"link"=>$row['link2']
),
...,
...,
array (
"title"=>$row['title10'],
"desc"=>$row['desc10'],
"link"=>$row['link10']
)
);
}

PHP Arrays, Serialization and Unserialization

I have a problem. I have a website with people and different transactions they make to and from a fake online bank. I want to be able to store an array of each person's transactions on my mysql database. I want each transaction to be defined as an associative array with a timestamp and the sql query that represents their transaction with the "bank".
Then I want those, after being serialized, to be the values of a transactions array that holds all of their transactions. Then I want to serialize that and store it in the database so that later I can add a transaction by unserializing it and appending a serialized array of another transaction to it. So far this code below works except that it just overwrites the one transaction and doesn't append a new one. I'd really appreciate any help.
Thanks in advance
function modify_transactions($row, $sql)
{
$sql=mysql_real_escape_string($sql);
if(isset($row["TRANSACTIONS"]))
{
$transactions = unserialize($row["TRANSACTIONS"]);
}
else
{
$transactions = array();
}
$transaction_array = array("timestamp"=>time(),"query"=>$sql);
$transaction_data = serialize($transaction_array);
$transactions[] = $transaction_data;
$transactions_upload = serialize($transactions);
$name = $row["NAME"];
$query = "UPDATE band.students SET TRANSACTIONS = '$transactions_upload' WHERE students.NAME = '$name'";
mysql_query($query);
}
If I were you, I'd rather go for a new table where every entry would represent a transaction and that had a foreign key student_id.
That'd be much, much, much cleaner and more flexible and scalable (i.e. what if you want to show the last 3 transactions of user X? What if a user had several million transactions?).
First, you don't need to serialize each array, then serialize again. Serialize is recursive:
$array = array(
array(
'1',
array()
),
array(
'2',
array()
)
);
$serialized = serialize($array);
$unserialized = unserialize($serialized);
echo "<pre>";
print_r($unserialized);
echo "</pre>";
Prints:
Array
(
[0] => Array
(
[0] => 1
[1] => Array
(
)
)
[1] => Array
(
[0] => 2
[1] => Array
(
)
)
)
So just serialize right before inserting into the database.
Second, you should change your database structure. Like vzwick mentioned, create a new table with a foreign key of the student. That way each entry represents a transaction.
Also, why are you storing the actual SQL query? That doesn't make any sense to me. Why don't you actually make a fake transaction?

Categories