Deleting index of JSON Array in PHP, creating string version of index? - php

I'm trying to get a sampling of PHP to work but I'm having a bit of an issue.
Initially, if I just create JSON data and save it to a file the structure looks as follows
[{"id":"519d4434e39ef","title":"event 3","start":"1369108800","end":"1369195199"},
{"id":"519d4430333c1","title":"event 2","start":"1368676800","end":"1368763199"},
{"id":"519d442a2b29c","title":"event 1","start":"1368504000","end":"1368590399"}]
That is created with the following code sample
$msg = array('id' => uniqid(),
'title' => $_POST['title'],
'start' => $_POST['start'],
'end' => $_POST['end']);
$data = get_data();
array_unshift($data, $msg);
file_put_contents($data_file, json_encode($data))
But, if I try to delete an item in that set of JSON data with this
$deleteId = $_POST['id'];
$data = get_data();
$index = -1;
for($i=0; $i < count($data); $i++){
if($data[$i]['id'] == $deleteId){
$index = $i;
break;
}
}
if($index != -1){
unset($data[$index]);
}
file_put_contents($data_file, json_encode($data))
The file ends up looking like the following
{"0":{"id":"519d4434e39ef","title":"event 3","start":"1369108800","end":"1369195199"},
"2":{"id":"519d442a2b29c","title":"event 1","start":"1368504000","end":"1368590399"}}
I don't see why this is happening.

Unset preserves indexes, creating the structure you are seeing. See this answer about using splice if you want to change the array, and re-index the items.

Related

How do i update multiple rows with multiple condition in Code Igniter

I am just learning PHP and using the Codeigniter framework.
I'm using this code in my controller when inserting new data and it's working.
//INSERT MULTI ROWS TABEL harga_inventori
$kode_inventori = $_POST['kode_inventori'];
$result = array();
foreach($_POST['kode_kategori_pelanggan'] AS $key => $val){
$result[] = array(
"kode_kategori_pelanggan" => $_POST['kode_kategori_pelanggan'][$key],
"kode_inventori"=>$kode_inventori,
"harga" => $_POST['harga_jual'][$key],
"diskon" => $_POST['diskon'][$key]
);
}
$res = $this->db->insert_batch('harga_inventori', $result);
redirect("inventori");
But when I'm using the same pattern for the updating function, it's not working at all.
for($i = 0; $i < count($_POST['harga_jual'][$i]); $i++) {
if($_POST['kode_kategori_pelanggan'][$i] != '') {
$res[] = array(
'harga' => $_POST['harga_jual'][$i],
'diskon' => $_POST['diskon'][$i],
);
$this->db->where('kode_inventori',$_POST['kode_inventori']);
$this->db->where('kode_kategori_pelanggan',$_POST['kode_kategori_pelanggan'][$i]);
$this->db->update('harga_inventori',$res);
}
}
redirect("inventori");
I'm trying the update_batch() but I got many errors, so I'm using for loop and updating a single row at a time.
What could be the problem here?
Its only a typo. You should pass the array $res not $data, and change $res[] to $res since it is not needed. You should also check with isset() to prevent errors of undefined:
for($i = 0; $i < count($_POST['harga_jual'][$i]); $i++) {
if(isset($_POST['kode_kategori_pelanggan'][$i])) {
$res = array(
'harga' => $_POST['harga_jual'][$i],
'diskon' => $_POST['diskon'][$i],
);
$this->db->where('kode_inventori',$_POST['kode_inventori']);
$this->db->where('kode_kategori_pelanggan',$_POST['kode_kategori_pelanggan'][$i]);
$this->db->update('harga_inventori',$res);
}
}
redirect("inventori");
It would help to see some of your data to know what you are trying to do. It seems a little strange that you initiate the counter $i at the same time using it as an array key in the for loop like this: for($i = 0; $i < count($_POST['harga_jual'][$i]); $i++)
It would help to know how the data in your $_POST looks like. You could try to remove the [$i] in your for loop. I would also check each POST variable it they are set before using them, something like:
for($i = 0; $i < count($_POST['harga_jual']); $i++) {
if(isset($_POST['kode_kategori_pelanggan'][$i])) {
// CHECK IF POST VARIABLES IS SET AND IF NOT SET A DEFAULT VALUE (IN THIS EXAMPLE AN EMPTY STRING):
$harga_jual = isset($_POST['harga_jual'][$i]) ? $_POST['harga_jual'][$i] : '';
$diskon = isset($_POST['diskon'][$i]) ? $_POST['diskon'][$i] : '';
$kode_inventori = isset($_POST['kode_inventori']) ? $_POST['kode_inventori'] : '';
$kode_kategori_pelanggan = $_POST['kode_kategori_pelanggan'][$i]; // ALREADY CHECKED ISSET ABOVE...
$data = array(
'harga' => $harga_jual,
'diskon' => $diskon,
);
$this->db->where('kode_inventori',$kode_inventori);
$this->db->where('kode_kategori_pelanggan', $kode_kategori_pelanggan);
$this->db->update('harga_inventori', $data);
}
}
redirect("inventori");

SimpleXML expecting array error PHP

ok below is my code
<?php
// Last 10 Jobs
function last10IT(){
$xml = simplexml_load_file('http://www.cv-library.co.uk/cgi-bin/feed.xml?affid=101899');
$new_array = array();
//$limit = 5;
//$c = 0;
foreach ($xml->jobs->job as $job) {
// if ($limit == $c) {
// break;
// }
$jobref = $job->jobref;
$title = $job->title;
$date = $job->date;
$new_array[$jobref.$date] = array(
'jobref' => $jobref,
'date' => $date,
'title' => $title,
'salary' => $job->salary,
'location' => $job->location,
);
}
}
ksort($new_array);
$showl = 10;
$n = 0;
foreach ($new_array as $date => $listing) {
print $listing['title'] . PHP_EOL;
}
?>
All I want it to do is filter by category & display a max of 10 results
for example
IT
so is there a way I can pass the category value into the function that I want it to filter by
instead of having to replicate for each category
All I get is :
Warning: ksort() expects parameter 1 to be array, null given in
C:\wamp\www\RECRUITMENTFAIR\functions.php on line 28
Please help guys
It something SO simple causing this error but its driving me mad because I just cannot see it
it is relative simple: you try to use the variable $new_array out of scope:
it is defined within your last10IT() function, but the function ends after the first foreach.
you should either return the array and call the function to get the array or move the part with the ksort and the printing into the function, depending on your needs.
Also was having issues by not having the PHP Extension xmlrpc enabled !
what a tool !
Thats why i was getting failed to open half the time

What is the best way to search through an array to return the key of a sub value

I'm trying to filter an array (derived from a json object), so as to return the array key based on the value. I'm not sure if array search $key = array_search($value, $array); is the best way to do this (I can't make it work), and I think there must be a better way.
So far I've got this, but it isn't working. Grateful for any help!
public function getBedroomData(array $data,$num_beds = null,$type) {
$data = (array) $data;
if($num_beds > 0) {
$searchstring = "avg_".$num_beds."bed_property_".$type."_monthly";
} else {
$searchstring = "avg_property_".$type."_monthly";
}
$avg_string = array_search($data, $searchstring);
return $avg_string;
}
The array consists of average property prices taken from the nestoria api as follows:
http://api.nestoria.co.uk/api?country=uk&pretty=1&action=metadata&place_name=Clapham&price_type=fixed&encoding=json
This returns a long json object. My problem is that the data isn't consistent - and I'm looking for the quickest (run time) way to do the following:
$data['response']['metadata']['0'] //= data to return, [0] unknown
$data['response']['metadata']['0']['metadata_name'] = "avg_1bed_property_rent_monthly" //= string I know!
$data['response']['metadata']['1'] //= data to return, [1] unknown
$data['response']['metadata']['1']['metadata_name'] = "avg_1bed_property_buy_monthly" //= string I know!
$data['response']['metadata']['2'] = //= data to return, [2] unknown
$data['response']['metadata']['2']['metadata_name'] = "avg_2bed_property_buy_monthly" //= string I know!
.....
.....
.....
$data['response']['metadata']['10'] = avg_property_rent_monthly
$data['response']['metadata']['11'] = avg_property_buy_monthly
$data['response']['metadata'][most_recent_month] = the month reference for getting the data from each metadata list..
It isn't possible to filter the initial search query by number of bedrooms as far as I can work out. So, I've just been array slicing the output to get the information I've needed if bedrooms are selected, but as the data isn't consistent this often fails.
To search inside that particular json response from nestoria, a simple foreach loop can be used. First off, of course call the json data that you need. Then, extract the whole data, the the next step if pretty straightforward. Consider this example:
$url = 'http://api.nestoria.co.uk/api?country=uk&pretty=1&action=metadata&place_name=Clapham&price_type=fixed&encoding=json';
$contents = file_get_contents($url);
$data = json_decode($contents, true);
$metadata = $data['response']['metadata'];
// dummy values
$num_beds = 1; // null or 0 or greater than 0
$type = 'buy'; // buy or rent
function getBedroomData($metadata, $num_beds = null, $type) {
$data = array();
$searchstring = (!$num_beds) ? "avg_property_".$type."_monthly" : "avg_".$num_beds."bed_property_".$type."_monthly";
$data['metadata_name'] = $searchstring;
$data['data'] = null;
foreach($metadata as $key => $value) {
if($value['metadata_name'] == $searchstring) {
$raw_data = $value['data']; // main data
// average price and data points
$avg_price = 0;
$data_points = 0;
foreach($raw_data as $index => $element) {
$avg_price += $element['avg_price'];
$data_points += $element['datapoints'];
}
$data_count = count($raw_data);
$price_average = $avg_price / $data_count;
$data_points_average = $data_points / $data_count;
$data['data'][] = array(
'average_price' => $price_average,
'average_datapoints' => $data_points_average,
'data' => $raw_data,
);
}
}
return $data;
}
$final = getBedroomData($metadata, $num_beds, $type);
print_r($final);

CSV file to flat array with materialized path

I have CSV file which contains a list of files and directories:
Depth;Directory;
0;bin
1;basename
1;bash
1;cat
1;cgclassify
1;cgcreate
0;etc
1;aliases
1;audit
2;auditd.conf
2;audit.rules
0;home
....
Each line depends on the above one (for the depth param)
I would like to create an array like this one in order to store it into my MongoDB collection with Materialized Paths
$directories = array(
array('_id' => null,
'name' => "auditd.conf",
'path' => "etc,audit,auditd.conf"),
array(....)
);
I don't know how to process...
Any ideas?
Edit 1:
I'm not really working with directories - it's an example, so I cannot use FileSystems functions or FileIterators.
Edit 2:
From this CSV file, I'm able to create a JSON nested array:
function nestedarray($row){
list($id, $depth, $cmd) = $row;
$arr = &$tree_map;
while($depth--) {
end($arr );
$arr = &$arr [key($arr )];
}
$arr [$cmd] = null;
}
But i'm not sure it's the best way to proceed...
This should do the trick, I think (it worked in my test, at least, with your data). Note that this code doesn't do much error checking and expects the input data to be in proper order (i.e. starting with level 0 and no holes).
<?php
$input = explode("\n",file_get_contents($argv[1]));
array_shift($input);
$data = array();
foreach($input as $dir)
{
if(count($parts = str_getcsv($dir, ';')) < 2)
{
continue;
}
if($parts[0] == 0)
{
$last = array('_id' => null,
'name' => $parts[1],
'path' => $parts[1]);
$levels = array($last);
$data[] = $last;
}
else
{
$last = array('id' => null,
'name' => $parts[1],
'path' => $levels[$parts[0] - 1]['path'] . ',' . $parts[1]);
$levels[$parts[0]] = $last;
$data[] = $last;
}
}
print_r($data);
?>
The "best" way to go would be to not store your data in CSV format, as it's the Wrong Tool For The Job.
That said, here you go:
<?php
$lines = file('/path/to/your/csv_file.csv');
$directories = array();
$path = array();
$lastDepth = NULL;
foreach ($lines as $line) {
list($depth, $dir) = str_getcsv($line, ';');
// Skip headers and such
if (!ctype_digit($depth)) {
continue;
}
if ($depth == $lastDepth) {
// If this depth is the same as the last, pop the last directory
// we added off the stack
array_pop($path);
} else if ($depth == 0) {
// At depth 0, reset the path
$path = array();
}
// Push the current directory onto the path stack
$path[] = $dir;
$directories[] = array(
'_id' => NULL,
'name' => $dir,
'path' => implode(',', $path)
);
$lastDepth = $depth;
}
var_dump($directories);
Edit:
For what it's worth, once you have the desired nested structure in PHP, it would probably be a good idea to use json_encode(), serialize(), or some other format to store it to disk again, and get rid of the CSV file. Then you can just use json_decode() or unserialize() to get it back in PHP array format whenever you need it again.

Manually build JSON encodable array in PHP

This is kind of a strange one. I have a CSV that I'm uploading and passing to a PHP script that parses it into arrays, encodes it into a JSON string and sends it back to be further processed by my Javascript. However, I am having difficulty getting the response in a format that is easily parsed. Maybe it can be parsed, I'm just not sure how to access the data within.
PHP script for handling and parsing the CSV:
<?php
$file = $_FILES['file'];
$tmp = $file['tmp_name'];
$row = 1;
$json = array();
if(($handle = fopen($tmp, 'r')) !== false){
while(($data = fgetcsv($handle, 10000, '\n')) !== false){
$num = count($data);
$row++;
for($i = 0; $i < $num; $i++){
$values = split(',', $data[$i]);
$value = array(
sName => $values[0],
sNick => $values[1],
sEmail => $values[2],
sSSOID => $values[3],
sPwd => $values[4],
sConfPwd => $values[5],
sDescr => $values[6]
);
array_push($json, $value);
}
print_r(json_encode($json));
}
fclose($handle);
}
?>
The output ends up being an iterative response where the first array contains the first row of the CSV and the second array contains the first and second rows (the third array contains the first, second, and third, etc. etc.). The very last array is the response that I want. It is a well-formed JSON string; I am just unsure of how to get only that response.
Sample response:
[{"sName":"John Doe","sNick":"John","sEmail":"jdoe#email.com","sSSOID":"jdoe","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes cats"}][{"sName":"John Doe","sNick":"John","sEmail":"jdoe#email.com","sSSOID":"jdoe","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes cats"},{"sName":"Bill Frank","sNick":"Bill","sEmail":"bfrank#email.com","sSSOID":"bfrank","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes dogs"}][{"sName":"John Doe","sNick":"John","sEmail":"jdoe#email.com","sSSOID":"jdoe","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes cats"},{"sName":"Bill Frank","sNick":"Bill","sEmail":"bfrank#gmail.com","sSSOID":"bfrank","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes dogs"},{"sName":"Sam Smith","sNick":"Sam","sEmail":"ssmith#email.com","sSSOID":"ssmith","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes music"}]
The only response I need is the final array:
[{"sName":"John Doe","sNick":"John","sEmail":"jdoe#email.com","sSSOID":"jdoe","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes cats"},{"sName":"Bill Frank","sNick":"Bill","sEmail":"bfrank#email.com","sSSOID":"bfrank","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes dogs"},{"sName":"Sam Smith","sNick":"Sam","sEmail":"ssmith#email.com","sSSOID":"ssmith","sPwd":"Admin1234","sConfPwd":"Admin1234","sDescr":"Likes music"}]
You might want to use
$json[] = $value;
instead of array_push and
echo json_encode($json);
instead of print_r. Also, move the print_r/echo call out of the while loop.
Move this line to after the fclose:
print_r(json_encode($json));
Try this:
$index = count($json) - 1;
echo json_encode($json[$index]);
Decode the JSON in your Javascript app, which will produce an array, then use .pop() to get the last value:
var json = json_decode('[{"sName" ......... ');
var lastelement = json.pop();

Categories