Datetime format in PHP with MongoDB - javascript

I'm getting problems while filtering data from a MongoDB where documents have a "iso_date" field like
ISODate("2010-08-01T00:00:00Z")
in the following .php file,
<?php
$date_a = $_GET['date_a'];
$date_b = $_GET['date_b'];
$m = new MongoClient('mongodb://127.0.0.1:xxxxx');
$db = $m->db;
$collection = $db->collection;
$res = $collection->find(array(
'iso_date' => array('$gte' => $date_a, '$lte' => $date_b)
));
$m->close();
echo json_encode($res);
?>
where date_a and date_b are created in javascript. I've tried to add string "T00:00:00Z" to YYYY-MM-DD dates, but the result is always empty (and I'm sure it shouldn't be).
How can I solve this? I'd like not to convert everything to strings, and to keep a datetime format.

Try this :
$collection = $db->collection;
$start = $_GET['date_a'];
$end = $_GET['date_a'];
// find dates between 1/15/2010 and 1/30/2010
$collection->find(array("iso_date" => array('$gt' => $start, '$lte' => $end)));

Your $date_a and $date_b need to be instances of MongoDate (since you're using legacy driver chridam's answer may not work).

Related

parse into another array contain xml child node using php

currently, im having problem to parse xml node in array using condition where parse with <mo> as separator
this is my array(0)
Array([0] => <mi>x</mi><mo>+</mo><mn>2</mn><mo>=</mo><mn>3</mn>);
i want to parse like this
Array[0] => <mi>x</mi>
Array[1] =><mo>+</mo><mn>2</mn>
Array[2]=><mo>=</mo><mn>3</mn>
this is my coding
<?
$result(0)="<mi>x</mi><mo>+</mo><mn>2</mn><mo>=</mo><mn>3</mn>";
$result1= new simplexml_load_string($result);
$arr_result=[];
foreach($result1 as $key => $value){
$exp_key = explode('<', $key);
if($key[0] == 'mo'){
$arr_result[] = $value;
}
print_r($arr_result);
}
if(isset($arr_result)){
print_r($arr_result);
}
?>
thanks in advance !
The approach with XML seems excessive since what you really want is to pull out substrings of a string based on a delimiter.
Here is a working example. It works by finding the position of <mo> and cutting off that section, then searching for the next <mo> in the remain string.
<?php
$result(0)="<mi>x</mi><mo>+</mo><mn>2</mn><mo>=</mo><mn>3</mn>";
$res = $result(0);
$arr_result=[];
while($pos = strpos($res, "<mo>", 1)) {
$arr_result[] = substr($res, 0, $pos); // grab first match
$res = substr($res, $pos); // grab the remaining string
}
$arr_result[] = $res; // add last chunk of string
print_r($arr_result);
?>
Your code above has several issues.
First:
$result1= new simplexml_load_string($result); // simplexml_load_string() is a function not a class
Second:
$key and $value do not contain the '<' and '>' so, this part:
$exp_key = explode('<', $key); will never do anything and isn't needed.
Third:
If your code did work it would only return array('+', '=') because you are appending the data inside the mo element to the result array.

Return multiple values through Jquery post()

I've returned 2 dates from a PHP script through $.post(). Then I'm trying to break up the results into two variables (the commented out portion under the console.log) , instead of appearing in one variable.
Below is the jquery code:
$.post('api/displayDBSetTimes.php', function(data) {
var obj = JSON.parse(data);
var htmlToInsert = obj.map(function (item) {
console.log(item.DB_ST);
/* var db_st = item.DB_ST;
var db_et = item.DB_ET;
return db_st + " " + db_et;*/
return item;
});
$('#oecd').html(htmlToInsert);
});
The PHP is below. I formatted the dates in the PHP script before sending out in JSON. The commented out jquery code above worked before I formatted the dates in PHP:
<?php
include_once("../include/sessions.php");
$select = "SELECT start_time AS DB_ST, end_time AS DB_ET FROM countdown WHERE tid = 1;";
$query = mysqli_query($dbc, $select);
if($query){
$out = array();
while ($row = $query->fetch_assoc())
{
$out[] = date('D, m-d-Y H:i:s A', strtotime($row['DB_ST']));
$out[] = date('D, m-d-Y H:i:s A', strtotime($row['DB_ET']));
}
// encode array as json and output it for the ajax script
echo json_encode($out);
}
?>
Every time I try to refer to the PHP variable in the jQuery $post() function (ie. item.DB_ST in the console.log) it returns as undefined, but if I remove the PHP variable reference, the 2 dates come back as one big string. I don't want that. I don't know why it's coming back undefined if I reference one part of the array.
Could someone help me? Would ajax() be better for something like this? The help would be much appreciated.
Set associative arrays in your PHP file...
$out['DB_ST'] = date('D, m-d-Y H:i:s A', strtotime($row['DB_ST']));
$out['DB_ET'] = date('D, m-d-Y H:i:s A', strtotime($row['DB_ET']));
And in your $.post you have to indicate the response is going to be in JSON format...
$.post('api/displayDBSetTimes.php', function(data) {
/* Here you can access directly to data.DB_ST and data.DB_ET */
},'json');
I hope it helps.
You need to use associative array in PHP, in order to achieve key-value pairs.
$out['DB_ST'] = date('D, m-d-Y H:i:s A', strtotime($row['DB_ST']));
$out['DB_ET'] = date('D, m-d-Y H:i:s A', strtotime($row['DB_ET']));

Using PHP string in SQL query works when typed in but not when generated via javascript

$query = "
select * from tablename where userid = :uid AND date = :date
";
$query_params = array(
':uid' => $_SESSION['user']['uid'],
':date' => $date
);
try
{
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
I am trying to run this simple SQL query via PHP. When I hard-code a string of a date like $date = '2016-07-29'; then I get the proper number of results. When I dynamically generate the same string using javascript like
$date = '<script> var currentdate = new Date();
document.write(currentdate.getFullYear()+"-"+
("0"+(currentdate.getMonth()+1)).slice(-2)+"-"+
("0"+currentdate.getDate()).slice(-2));
</script>';
then I get 0 results. Any ideas? Echoing $date in both instances produces the same result (type = string).

json data value type

I want to change json array values from strings to float values which from php script. It's all string type. I want it as a float type.
[{"year":"2008","value":"4169.20"},
{"year":"2009","value":"4067.50"},
{"year":"2010","value":"4848.40"},
{"year":"2011","value":"5654.80"},
{"year":"2012","value":"6071.50"}]
But i want it to look like. Is it possible?
[{"year":"2008","value":4169.20},
{"year":"2009","value":4067.50},
{"year":"2010","value":4848.40},
{"year":"2011","value":5654.80},
{"year":"2012","value":6071.50}]
The simplest way is to cast value to float before encoding data to the JSON.
But if you want to work only in JS:
var data = [ /* your data */ ];
data.forEach(function(item){
item.value = +item.value;
});
Output:
[
{"year":"2008","value":4169.2},
{"year":"2009","value":4067.5},
{"year":"2010","value":4848.4},
{"year":"2011","value":5654.8},
{"year":"2012","value":6071.5}
]
<?php
$data = '[{"year":"2008","value":"4169.20"},
{"year":"2009","value":"4067.50"},
{"year":"2010","value":"4848.40"},
{"year":"2011","value":"5654.80"},
{"year":"2012","value":"6071.50"}]';
$a = json_decode($data);
$b = array();
foreach ($a as $key => $v) {
$c['year'] = $v->year;
$c['value'] = (float) $v->value;
$b[] = $c;
}
echo '<pre>';
print_r(json_encode($b));
echo '</pre>';
?>
Demo
use javascript parseFloat() function:
e.g.
var b = parseFloat("10.00")
I see only JS answers. I don't know what is your intention, but if you have the jsong string in PHP you can use something like this:
$json = ' [
{"year":"2008","value":"4169.20"},
{"year":"2009","value":"4067.50"},
{"year":"2010","value":"4848.40"},
{"year":"2011","value":"5654.80"},
{"year":"2012","value":"6071.50"}
]';
$jsonArray = json_decode($json);
foreach($jsonArray as $key => &$subArray)
{
$subArray->value = (float) $subArray->value;
}
echo json_encode($jsonArray);
You have 2 options.
Option 1.
In the backend of your application (the php code) you can cast "value" to be float. E.g.:
$floatValue = (float) $strValue;
Option 2.
If you can't edit the backend use parseFloat on each "value". It will produce floats from the strings in your response.
with preg_replace
$json = preg_replace('/"value":"(\d+\.\d+)"/', '"value":$1',$json);

Chunking MySQL array with json encode

I know there are existing some Questions about Chunking a mysql array in php, but my problem is, that I want to keep the output in JSON.
Scenario:
I want to get data from mysql, do some stuff with it ( like time formatting ) and output it in JSON.
The JSON data is parsed in the browser and visualized over a javascript chart.
Problem:
All of the above is working, but because of the huge amount of data, I'm getting an out of memory error, when I select bigger date ranges to output.
The Idea of directly sending out each x-lines of data is not working because of the JSON format it needs to be. Several JSON chunks won't work, it needs to be one for the chart.
So in the end I need to chunk the data but keep it as one big JSON.
(And setting up the memory limit is not really a solution.)
Ideas:
One Idea would be, to let the browser chunk the date range and ask the data as chunks & then put them together.
Of course this would work, but if there is a way to do this server side, it would be better.
Code:
private function getDB($date1, $date2){
$query = 'SELECT * FROM `db1`.`'.$table.'` WHERE `date` BETWEEN "'.$date1.'" AND "'.$date2.'" order by `date`;';
// date = datetime !
$result = $this->db->query($query);
$array = array();
while ( $row = $result->fetch_assoc () ) {
$array[] = array( strtotime($row[ 'date' ])*1000 , (float)$row[ 'var' ] );
// the formatting needs to be done, so the chart accepts it..
}
$result->close();
return json_encode($array);
}
Since this is not an option,
ini_set("memory_limit","32M")
perhaps you can add LIMIT to the function paramaters and query:
private function getDB($date1, $date2, $start, $pageSize){
$query = 'SELECT * FROM `db1`.`'.$table.'` WHERE `date` BETWEEN "'.$date1.'" AND "'.$date2.'" order by `date` LIMIT $start, $pageSize;';
// date = datetime !
$result = $this->db->query($query);
$array = array();
while ( $row = $result->fetch_assoc () ) {
$array[] = array( strtotime($row[ 'date' ])*1000 , (float)$row[ 'var' ] );
// the formatting needs to be done, so the chart accepts it..
}
$result->close();
return json_encode($array);
}
Then setup a for loop in javascript, call this with Ajax, incrementing the $start variable each time.
Store each responseText.substr(1).substr(-1) in an array.
When the responseText is "", all of the records have been returned.
.join the array with a comma, then add a new opening and closing "{ }", and you should have a JSON equivalent to all records.
Minimal parsing, and you'll be using built-in functions for most of it.
var startRec=0;
var pageSize=50;
var xmlhttp=new XMLHttpRequest();
var aryJSON=[];
var JSON;
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
if(xmlhttp.responseText==""){ //Might need to check for "{}" here instead of ""
//All records are received
JSON="{" + aryJSON.join(",") + "}";
aryJSON=[];
startRec=0
}else{
aryJSON.push(xmlhttp.responseText.substr(1).substr(-1));
startRec+=pageSize;
getNextPage();
}
}
}
function getNextPage(){
xmlhttp.open("GET","your.php?start=" + startRec + "&pageSize=" + pageSize,true);
xmlhttp.send();
}
I would recommend that you have the server send the browser exactly what it needs to create the table. Parsing can be a heavy task, so why have the client do that lifting?
I would have your backend send the browser some kind of data structure that represents the table (i.e. list of lists), with all the formatting already done. Rendering the table should be faster and less memory-intensive.
One way of answer would be, to do the chunking on the server, by giving out the JSON, removing the leading [ & ].
#apache_setenv('no-gzip', 1);
#ini_set('zlib.output_compression', 0);
#ini_set('implicit_flush', 1);
$array = array();
echo '[';
$started = false;
while ( $row = $result->fetch_assoc () ) {
$array[] = [ strtotime($row[ 'datetime' ])*1000 , (float)$row[ 'var' ] ];
if(sizeof($array) == 1000){
if($started){
echo ',';
}else{
$started = true;
}
echo substr(substr(json_encode($array),1), 0, -1);
// converting [[datetime1, value1],[datetime2, value2]]
// to [datetime1, value1],[datetime2, value2]
ob_flush();
$array = array();
}
}
if($started)echo ',';
$this->flushJSON($array);
echo ']';
flush();
$result->close();
This is working and reducing the ram usage to 40%.
Still it seems that Apache is buffering something, so the ram usage increases over the time, the script is running. (Yeah, the flush is working, I debugged that, that's not the problem.)
But because of the remaining increase, the fastest way to achieve a clean chunking is to do this like alfadog67 pointed it out.
Also, to mention it, I had to disable the output compression, otherwise apache wouldn't flush it directly..

Categories