I am using codeigniter update_batch function.
I want to pass an array as the third parameter (where clause) to update_batch.
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name 2' ,
'date' => 'My date 2'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name 2' ,
'date' => 'Another date 2'
)
);
Instead of this:
$this->db->update_batch('mytable', $data, 'title');
I want to do this:
$this->db->update_batch('mytable', $data, array('title','name'));
So multiple where conditions added.
Is this possible?
You could do this by creating your method for batch update in your model Test_model for example because Codeigniter does not supports multiple where condition in native update_batch, so example below:
public function update_batch_custom($table_name, $data, $indexes) {
if (empty($data) || empty($indexes)){
return 'Data or indexes must not be empty';
}
$db = $this->load->database('test_db', TRUE);
$sql = 'UPDATE ' . $table_name . ' SET ' . "\n";
//columns on which is done actual update
$columns = [];
foreach ($data[0] as $key => $value) {
if (!in_array($key, $indexes)){
$columns[] = $key;
}
}
/*
* forming WHEN .. THEN sql parts and WHERE condition
*/
$parts = [];
$where = [];
foreach ($data as $row) {
foreach ($columns as $column) {
$sql_part = ' WHEN (';
foreach ($indexes as $index) {
$sql_part .= $index . '= \''.$row[$index] . '\' AND ';
$where[$index][] = $row[$index];
}
$sql_part = substr($sql_part, 0, -4);
$sql_part .= ') THEN \'' . $row[$column] . '\'';
$parts[$column][] = $sql_part;
}
}
/*
* connecting WHEN .. THEN parts for each column to be updated
*/
foreach ($columns as $column) {
$sql .= $column .'= CASE ';
foreach ($parts[$column] as $sql_part) {
$sql .= $sql_part;
}
$sql .= ' ELSE ' . $column . ' END,';
}
/*
* adding WHERE part
*/
$sql = substr($sql, 0, -1);
$sql .= ' WHERE ';
foreach ($indexes as $index) {
if ( count($where[$index]) > 0){
$unique_where = array_unique($where[$index]);
$sql .= $index . ' IN (\'' . join('\',\'', $unique_where) . '\') AND ';
}
}
$sql = substr($sql, 0, -4);
$sql .= ';';
return $db->query($sql);
}
You can use below code to update your data:
$this->db->update("TableName",[dataarray],[where condition array]);
This update_batch function does not allow WHERE parameter, but you can try splitting it before calling the function.
Try this:
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name 2' ,
'date' => 'My date 2'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name 2' ,
'date' => 'Another date 2'
)
);
$this->db->where('name','My Name 2');
$this->db->update_batch('mytable', $data, 'title');
Controller:
$chunk1 = array_chunk($data,100);
for($i=0;$i < count($chunk1);$i++) {
$this->upload_model->update_data($chunk1[$i],'My Name 2');
}
Model:
public function update_data($data='',$name=''){
$this->db->where('name',$name);
$this->db->update_batch('mytable', $data, 'title');
}
Remember, my WHERE parameter is a static value.
You could always do this:
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name 2' ,
'date' => 'My date 2'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name 2' ,
'date' => 'Another date 2'
)
);
$this->db->where(array('title' => 'title', 'name' => 'name'));
$this->db->update_batch('mytable', $data);
Not tested.
UPDATE This lacks the required where parameter in update_batch().
Related
after 10 years I’m starting programming again, just for fun. I’m struggling with the following code in PHP:
This is what I get from the database:
$data[0] = ['id' => NULL, 'titel' => NULL, 'category_id' => NULL];
$data[1] = ['id' => '1', 'titel' => 'Apple', 'category_id' => '123'];
$data[2] = ['id' => '2', 'titel' => 'Pear', 'category_id' => '123'];
$data[3] = ['id' => '3', 'titel' => 'Orange', 'category_id' => '123'];
$data[6] = ['id' => '6', 'titel' => 'Strawberry', 'category_id' => '297'];
$data[7] = ['id' => '7', 'titel' => 'Blueberry', 'category_id' => '297'];
$data[8] = ['id' => '8', 'titel' => 'Raspberry', 'category_id' => '297'];
$data[12] = ['id' => '12', 'titel' => 'Cucumber', 'category_id' => '557'];
$data[13] = ['id' => '13', 'titel' => 'Pumpkin', 'category_id' => '557'];
That’s the string I have to generate for the javascript:
'choices': {
0: {
text: [''],
value: ['']
},
123: {
text: ['Apple', 'Pear', 'Orange'],
value: ['1', '2', '3']
},
297: {
text: ['Strawberry', 'Blueberry', 'Raspberry'],
value: ['6', '7', '8']
},
557: {
text: ['Cucumber', 'Pumpkin'],
value: ['12', '13']
}
}
Can someone help me on that one? I’m trying something like this, but struggling with:
$text = 'text: [';
$value = 'value: [';
$final_str = '';
$current_category_id = '';
foreach ($data as $foo) {
if (($foo['category_id'] != $current_category_id)) {
$text .= ']';
$value .= ']';
$final_str .= '}, ' . $product_id . ': { ' . $text . $value;
$text = 'text: [';
$value = 'value: [';
}
$text .= '\'' . $foo['titel'] . '\', ';
$value .= '\'' . $foo['id'] . '\', ';
$current_category_id = $foo['category_id'];
}
$text .= ']';
$value .= ']';
$final_str .= $current_category_id . ' { ' . $text . $value;
Thank you very much!
First things first: don't try to build that string by hand, you'll just get headaches. Instead, build up the array structure in PHP, and then use json_encode to convert it to JSON.
You can then either cheat and use the JSON directly as a JavaScript variable (always remember that JSON and JavaScript are not the same language, but JSON is almost always valid JavaScript), or use JSON.parse to parse it properly.
The next trick is that since you're building an associative array, you don't need to track the "current" category, you can just add each item into the right place:
$data_by_category = [];
foreach ( $data as $item ) {
// Force the vategory to be an integer, 0 for null
$category_id = (int)$item['category_id'];
// Set up the category the first time you see it
$data_by_category[$category_id] ??= ['text'=>[], 'value'=>[]];
// Add the items as you see them, forcing them to be strings
$data_by_category[$category_id]['text'][] = (string)$item['titel'];
$data_by_category[$category_id]['value'][] = (string)$item['id'];
}
Instead of manually building a string, you should generate the data structure and then output it via json_encode:
<?php
$return = [];
foreach($data as $d) {
$cat_id = intval($d['category_id']);
if (!isset($return[$cat_id])) {
$return[$cat_id] = [
'text' => [],
'value' => [],
];
}
$return[$cat_id]['text'][] = strval($d['titel']);
$return[$cat_id]['value'][] = strval($d['id']);
}
?>
<script>
...
'choices': <?= json_encode($return); ?>
...
</script>
If you do echo json_encode($return); it will output:
{"0":{"text":[""],"value":[""]},"123":{"text":["Apple","Pear","Orange"],"value":["1","2","3"]},"297":{"text":["Strawberry","Blueberry","Raspberry"],"value":["6","7","8"]},"557":{"text":["Cucumber","Pumpkin"],"value":["12","13"]}}
You can see it in action at https://3v4l.org/VrHXO
I have this function,
public function storeVals($vals)
{
$vals = explode(",", $vals);
foreach ($vals as $val)
{
$val = array('input'=>$val);
$this->db->insert('input', $val);
}
}
The function basically receives a string e.g: This,Is,An,Example
Then it turns the string into an array with "," as a delimiter.
Then it loops through the array and inserts the data into the DB.
Code Igniter, I think, already has the functionality to do this.
File: system/database/drivers/mysql/mysql_driver.php
function _insert_batch($table, $keys, $values)
{
return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
}
Any ideas on how I can use insert_batch() instead of looping and inserting will be highly appreciated.
Thank you.
In CodeIgniter, You can use batch_insert as:
public function storeVals($vals)
{
$vals = explode(",", $vals);
$yourArr = array();
foreach ($vals as $val)
{
$yourArr[] = array('input'=>$val); // store values in array
}
$this->db->insert('tableName', $yourArr);
}
You can also follow the CI example:
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name' ,
'date' => 'My date'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name' ,
'date' => 'Another date'
)
);
$this->db->insert_batch('mytable', $data);
// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')
Example Reference
CI 3 User Guide (Batch Insert)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP convert nested array to single array while concatenating keys?
Get array's key recursively and create underscore seperated string
Please, read the whole question before answering.
I have this multidimensional array:
$data = array(
'user' => array(
'email' => 'user#example.com',
'name' => 'Super User',
'address' => array(
'billing' => 'Street 1',
'delivery' => 'Street 2'
)
),
'post' => 'Hello, World!'
);
I want it flatten, transformed into:
$data = array(
'user.email' => 'user#example.com',
'user.name' => 'Super User',
'user.address.billing' => 'Street 1',
'user.address.delivery' => 'Street 2',
'post' => 'Hello, World!'
);
Important:
The keys are very important to me. I want them concatenated, separated by periods.
It should work with any level of nesting.
Thank you!
Something like this should work:
function flatten($array, $prefix = '') {
$result = array();
foreach($array as $key=>$value) {
if(is_array($value)) {
$result = $result + flatten($value, $prefix . $key . '.');
}
else {
$result[$prefix . $key] = $value;
}
}
return $result;
}
DEMO
Thanks for all the given answers.
I have transformed it in the following, which is an improved version. It eliminates the need of a root prefix, does not need to use references, it is cleaner to read, and it has a better name:
function array_flat($array, $prefix = '')
{
$result = array();
foreach ($array as $key => $value)
{
$new_key = $prefix . (empty($prefix) ? '' : '.') . $key;
if (is_array($value))
{
$result = array_merge($result, array_flat($value, $new_key));
}
else
{
$result[$new_key] = $value;
}
}
return $result;
}
Try this
<?php
$data = array(
'user' => array(
'email' => 'user#example.com',
'name' => 'Super User',
'address' => array(
'billing' => 'Street 1',
'delivery' => 'Street 2'
)
),
'post' => 'Hello, World!'
);
function prefixKey($prefix, $array)
{
$result = array();
foreach ($array as $key => $value)
{
if (is_array($value))
$result = array_merge($result, prefixKey($prefix . $key . '.', $value));
else
$result[$prefix . $key] = $value;
}
return $result;
}
var_dump(prefixKey('', $data));
?>
Outputs
array
'user.email' => string 'user#example.com' (length=16)
'user.name' => string 'Super User' (length=10)
'user.address.billing' => string 'Street 1' (length=8)
'user.address.delivery' => string 'Street 2' (length=8)
'post' => string 'Hello, World!' (length=13)
test this out here
i passed by reference so no need for returns. just hand over the array storage.
$store = array();
function flatten($array,&$storage,$parentKey = ''){
foreach($array as $key => $value){
$itemKey = (($parentKey)? $parentKey.'.':'').$key;
if(is_array($value)){
flatten($value,$storage,$itemKey);
} else {
$storage[$itemKey] = $value;
}
}
}
flatten($data,$store);
var_dump($store);
Use recursion such as this:
function process_data( $data, $parent_key ){
if ( ! is_array( $data ) ){
return $data;
}
$flattened_array = array();
foreach( $data as $key => $item ){
$flattened_key = $parent_key . '.' . $key;
$flattened_array[ $flattened_key ] = process_data( $item, $flattened_key );
}
return $flattened_array;
}
get stuck: given an array like:
$customers = array(
'C00005' => 'My customer',
'C02325' => 'Another customer',
'C01945' => 'Another one',
'C00586' => 'ACME inc.'
)
and given a querystring like ?customerID=C01945 ($_GET['customerID'] = 'C01945' ), how can I filter the array so that it returns:
$customers = array(
'C01945' => 'Another one'
)
You can just use array_instersect_key:
$myKey = $_GET['customerID']; // You should validate this string
$result = array_intersect_key($customers, array($mykey => true));
// $result is [$myKey => 'another customer']
Try Using foreach
$customers = array(
'C00005' => 'My customer',
'C02325' => 'Another customer',
'C01945' => 'Another one',
'C00586' => 'ACME inc.'
);
$_GET['customerID'] = 'C01945';
$result = array();
foreach($customers as $key => $value){
if($_GET['customerID'] == $key){
$result[$key] = $value;
}
}
print_r($result);
Using array_walk
$customerID = 'C01945';
$result = array();
array_walk($customers,function($v,$k) use (&$result,$customerID){if($customerID == $k){$result[$k] = $v;}});
Simply do -
$res = !empty($customers[$_GET['customerID']]) ? array($_GET['customerID'] => $customers[$_GET['customerID']]) : false;
You can use false or something like that to identify empty value.
For PHP>=5.6:
$customers = array_filter($customers,function($k){return $k==$_GET['customerID'];}, ARRAY_FILTER_USE_KEY);
http://sandbox.onlinephpfunctions.com/code/e88bdc46a9cd9749369daef1874b42ad21a958fc
For earlier version you can help yourself with array_flip:
$customers = array_flip(array_filter(array_flip($customers),function($v){return $v==$_GET['customerID'];}));
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP convert nested array to single array while concatenating keys?
Get array's key recursively and create underscore seperated string
Please, read the whole question before answering.
I have this multidimensional array:
$data = array(
'user' => array(
'email' => 'user#example.com',
'name' => 'Super User',
'address' => array(
'billing' => 'Street 1',
'delivery' => 'Street 2'
)
),
'post' => 'Hello, World!'
);
I want it flatten, transformed into:
$data = array(
'user.email' => 'user#example.com',
'user.name' => 'Super User',
'user.address.billing' => 'Street 1',
'user.address.delivery' => 'Street 2',
'post' => 'Hello, World!'
);
Important:
The keys are very important to me. I want them concatenated, separated by periods.
It should work with any level of nesting.
Thank you!
Something like this should work:
function flatten($array, $prefix = '') {
$result = array();
foreach($array as $key=>$value) {
if(is_array($value)) {
$result = $result + flatten($value, $prefix . $key . '.');
}
else {
$result[$prefix . $key] = $value;
}
}
return $result;
}
DEMO
Thanks for all the given answers.
I have transformed it in the following, which is an improved version. It eliminates the need of a root prefix, does not need to use references, it is cleaner to read, and it has a better name:
function array_flat($array, $prefix = '')
{
$result = array();
foreach ($array as $key => $value)
{
$new_key = $prefix . (empty($prefix) ? '' : '.') . $key;
if (is_array($value))
{
$result = array_merge($result, array_flat($value, $new_key));
}
else
{
$result[$new_key] = $value;
}
}
return $result;
}
Try this
<?php
$data = array(
'user' => array(
'email' => 'user#example.com',
'name' => 'Super User',
'address' => array(
'billing' => 'Street 1',
'delivery' => 'Street 2'
)
),
'post' => 'Hello, World!'
);
function prefixKey($prefix, $array)
{
$result = array();
foreach ($array as $key => $value)
{
if (is_array($value))
$result = array_merge($result, prefixKey($prefix . $key . '.', $value));
else
$result[$prefix . $key] = $value;
}
return $result;
}
var_dump(prefixKey('', $data));
?>
Outputs
array
'user.email' => string 'user#example.com' (length=16)
'user.name' => string 'Super User' (length=10)
'user.address.billing' => string 'Street 1' (length=8)
'user.address.delivery' => string 'Street 2' (length=8)
'post' => string 'Hello, World!' (length=13)
test this out here
i passed by reference so no need for returns. just hand over the array storage.
$store = array();
function flatten($array,&$storage,$parentKey = ''){
foreach($array as $key => $value){
$itemKey = (($parentKey)? $parentKey.'.':'').$key;
if(is_array($value)){
flatten($value,$storage,$itemKey);
} else {
$storage[$itemKey] = $value;
}
}
}
flatten($data,$store);
var_dump($store);
Use recursion such as this:
function process_data( $data, $parent_key ){
if ( ! is_array( $data ) ){
return $data;
}
$flattened_array = array();
foreach( $data as $key => $item ){
$flattened_key = $parent_key . '.' . $key;
$flattened_array[ $flattened_key ] = process_data( $item, $flattened_key );
}
return $flattened_array;
}