I have a long sql query with a lot of derived columns and I'm trying to get it displayed in an angular page. I reached the point where I'm getting a json response back from the db but its returning each row as one big object instead of an array. I'm using perl to query the db and I've tried a bunch of ways to parse it and I haven't gotten it yet.
The subroutine:
require fileWithAllImports.pl #has CGI, JSON, etc
%response = {};
$response{error}{code} = "0";
$response{error}{message} = "OK";
$sql = "select c.title as Content....";
$sql = &database_escape_sql($sql); #I think its self-explanatory what this does
%hash = &database_select_as_hash_with_auto_key(
$sql,"content ... "); #more columns
foreach $i ( keys %hash ) {
$id = $i;
$response{$i}{content} = $hash{$i}{content};
...
} #again all of the columns
print_json_response(%response);
The angular call:
$http.get("/folder/ofSubroutine.cgi")
.then(function(minutes_results) {
console.log(minutes_results);
and the json repsonse:
{"6":{"derivedcolumn":"123","anotherderived":"987",..},"11":{"derived column":"123"}...}
I believe ng-repeat only works with an array so how would I parse the response from the server into an array?
On the back end, you could place the data into a separate array instead of adding each row to the hash:
foreach $i ( keys %hash ) {
push #{$response{data}}, { id => $i,
content => $hash{$i}{content},
... ,
};
}
print_json_response( %response );
Or on the front end, convert your associative array to a regular array:
$http.get("/folder/ofSubroutine.cgi")
.then(function(minutes_results) {
console.log(minutes_results);
var minutes_results_as_array = [];
for (var key in minutes_results) {
if (key != "error") {
minutes_results[key].id = key;
minutes_results_as_array.push(minutes_results[key]);
}
}
// display minutes_results_as_array as you see fit
} );
I'm using Dropzone.js to upload multiple files in Laravel, which works fine uploads to my uploads folder but now I want the save the json object to the db.
Currently I have:
$file = Input::file('file');
$fileName = $file->getClientOriginalName();
$file->move(public_path().'/uploads/userfiles', $fileName);
return Response::json(array('filelink' => '/uploads/userfiles/' . $fileName));
So now how would I store this in my users table in the uploads column?
Depends what you want to store...
As I understand it, you want to associate uploads with a user? If you just want to store the filename, which may suffice, maybe do this:
// models/User.php
class User extends Eloquent {
// ...
public function setFilesAttribute(array $files)
{
$this->attributes['files'] = json_encode(array_values($files));
}
public function getFilesAttribute($files)
{
return $files ? json_decode($files, true) : array();
}
}
// Your script
$file = Input::file('file');
$fileName = $file->getClientOriginalName();
$file->move(public_path().'/uploads/userfiles', $fileName);
$user = User::find(1); // Find your user
$user->files[] = $fileName; // This may work, not too sure if it will being a magic method and all
$user->files = array_merge($user->files, [$fileName]); // If not, this will work
$user->save();
return Response::json(array('filelink' => '/uploads/userfiles/' . $fileName));
Something like this?
Of course, you could get more complex and create a model which represents a "file" entity and assign multiple files to a usre:
// models/File.php, should have `id`, `user_id`, `file_name`, `created_at`, `updated_at`
class File extends Eloquent {
protected $table = 'files';
protected $fillable = ['file_name']; // Add more attributes
public function user()
{
return $this->belongsTo('User');
}
}
// models/User.php
class User extends Eloquent {
// ...
public function files()
{
return $this->hasMany('File');
}
}
// Your script
$file = Input::file('file');
$fileName = $file->getClientOriginalName();
$file->move(public_path().'/uploads/userfiles', $fileName);
$user = User::find(1); // Find your user
$file = new File([
'file_name' => $fileName,
// Any other attributes you want, just make sure they're fillable in the file model
]);
$file->save();
$user->files()->attach($file);
return Response::json(array('filelink' => '/uploads/userfiles/' . $fileName));
i am creating project in yii+extjs. I am having poll table with pollid and pollQuestion. Option table is having pollid and options. Now during publishing question i am retrieving question from poll table and options of that question from option table. and sending this data in json_encoded format. i had desgined function as-
public function actionCreate()
{
$model=new poll();
$model->pollId=4;
$record1=poll::model()->findByPk($model->pollId);
//$data = $record1->getAttributes();
$data= $record1->getAttributes(array('pollId','pollQuestion'));
foreach ($record1->polloptions as $option)
{
$data = array_merge($data, $option->with('pollId')- >getAttributes());
}
//echo $data;
echo CJSON::encode($data);
}
Option table is having multiple options for same question. But by above method it is displaying only last option inserted in option table instead of displaying all options of same question. So how to display all options of same question.Please help me....
May be you could try:
public function actionCreate()
{
$model=new poll();
$model->pollId=4;
$record1=poll::model()->findByPk($model->pollId);
//$data = $record1->getAttributes();
$data= $record1->getAttributes(array('pollId','pollQuestion'));
foreach ($record1->polloptions as $option)
{
$optionArray = $option->getAttributes()
//if the 2 arrays havn't the same indexes
//this way u keep the key indexes
$data = $data + $optionArray;
//if the 2 arrays could have the same indexes
$data = array_push($data, $optionArray);
}
//echo $data;
echo CJSON::encode($data);
}
I'm making a "Download" controller using Symfony 2, that has the sole purpose of sending headers so that I can force a .csv file download, but it isn't working properly.
$response = new Response();
$response->headers->set('Content-Type', "text/csv");
$response->headers->set('Content-Disposition', 'attachment; filename="'.$fileName.'"');
$response->headers->set('Pragma', "no-cache");
$response->headers->set('Expires', "0");
$response->headers->set('Content-Transfer-Encoding', "binary");
$response->headers->set('Content-Length', filesize($fileName));
$response->prepare();
$response->sendHeaders();
$response->setContent(readfile($fileName));
$response->sendContent();
$fileName is a "info.csv" string. Such are my actions inside my controller, there's no return statement. When I tried returning the Response Object, the contents of the file were displayed in the browser, not my intended result.
The problem I've found is that in some pages I do get my info.csv file, but in anothers all I get is a message:
No webpage was found for the web address: http://mywebpage.com/download
Error 6 (net::ERR_FILE_NOT_FOUND): The file or directory could not be found.
I'm completely sure the file exists, so there must be another thing wrong. Also, routing.yml is working correctly, since I do get the file from other pages that also link to that path.
The Apache error log doesn't show anything about it.
Has anyone forced the download of a .csv file on Symfony 2 before? If so, what am I doing wrong?
Here is a minimal example that works just fine in production:
class MyController
public function myAction()
$response = $this->render('ZaysoAreaBundle:Admin:Team/list.csv.php',$tplData);
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename="teams.csv"');
return $response;
You can replace the render call with new response and response->setContent if you like.
Your comment about no return statement inside a controller is puzzling. Controllers return a response. Let the framework take care of sending the stuff to the browser.
I realize this post is kind of old and that there is, oddly enough, practically no good resources on how to do a CSV Export in symfony 2 besides this post at stackoverflow.
Anyways I used the example above for a client contest site and it worked quite well. But today I received an e-mail and after testing it myself, the code had broken - I was able to get the download working with a small amount of results, but the database now exporting over 31,000 rows it either simply showed the text or with chrome, just basically did nothing.
For anyone having issue with a large data export, this is what I manged to get to work, basically doing what Cerad suggested as an alternate way:
$filename = "export_".date("Y_m_d_His").".csv";
$response = $this->render('AppDefaultBundle:Default:csvfile.html.twig', array('data' => $data));
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Description', 'Submissions Export');
$response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
$response->headers->set('Content-Transfer-Encoding', 'binary');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Expires', '0');
$response->prepare();
$response->sendHeaders();
$response->sendContent();
EDIT: After more testing and upping the max seconds allowed, I realized the previous code was printing out the headers at the top so I've updated the code.
THis worked for me to export CSV and JSON.
Twig files are named : export.csv.twig, export.json.twig
The Controller :
class PrototypeController extends Controller {
public function exportAction(Request $request) {
$data = array("data" => "test");
$format = $request->getRequestFormat();
if ($format == "csv") {
$response = $this->render('PrototypeBundle:Prototype:export.' . $format . '.twig', array('data' => $data));
$filename = "export_".date("Y_m_d_His").".csv";
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
return $response;
} else if ($format == "json") {
return new Response(json_encode($data));
}
}
}
The Routing :
prototype_export:
pattern: /export/{_format}
defaults: { _controller: PrototypeBundle:Prototype:export, _format: json }
requirements:
_format: csv|json
The Twigs:
export.csv.twig (do your comma seperated thing here, this is just a test)
{% for row in data %}
{{ row }}
{% endfor %}
export.json.twig (data is sent json_encoded, this file is empty)
Hope this helps!
This is how I managed to get Silex to return a csv:
// $headers in an array of strings
// $results are the records returned by a PDO query
$stream = function() use ($headers, $results) {
$output = fopen('php://output', 'w');
fputcsv($output, $headers);
foreach ($results as $rec)
{
fputcsv($output, $rec);
}
fclose($output);
};
return $app->stream($stream, 200, array(
'Content-Type' => 'text/csv',
'Content-Description' => 'File Transfer',
'Content-Disposition' => 'attachment; filename="test.csv"',
'Expires' => '0',
'Cache-Control' => 'must-revalidate',
'Pragma' => 'public',
));
You may also need to do some Jiggery Pokery with Javascript (I was downloading Via AJAX) but this post was all I needed to get it working.
simple function you can use for every case to export an csv for download...
public function getResponse(array $data, $filename, $headers = array())
{
if(substr(strtolower($filename), -4) == '.csv') {
$filename = substr($filename, 0, -4);
}
$tmpFile = $this
->_getContainer()
->get('kernel')
->getRootDir()
. '/../var/tmp_'.substr(md5(time()),0,5);
if(file_exists($tmpFile)) unlink($tmpFile);
$handle = fopen($tmpFile, 'w');
foreach ($data as $i => $row) {
$row = (array) $row;
if($i == 0) fputcsv($handle, array_keys($row));
fputcsv($handle, $row);
}
fclose($handle);
$Response = new Response(file_get_contents($tmpFile));
unlink($tmpFile);
$filename = preg_replace('[^a-z0-9A-Z_]', '', $filename);
$headers = array_merge([
'Expires' => 'Tue, 01 Jul 1970 06:00:00 GMT',
'Cache-Control' => 'max-age=0, no-cache, must-revalidate, proxy-revalidate',
'Content-Disposition' => 'attachment; filename='.$filename.'.csv',
'Content-Type' => 'text/csv',
'Content-Transfer-Encoding' => 'binary',
], $headers);
foreach ($headers as $key => $val) {
$Response->headers->set($key, $val);
}
return $Response;
}
How about using Sonata's Exporter:
use Exporter\Writer\CsvWriter;
/**
* #param array $orders
*/
public function exportToCsv($orders)
{
$rootdir = $this->get('kernel')->getRootDir();
$filename = $rootdir . '/data/orders.csv';
unlink($filename);
$csvExport = new CsvWriter($filename);
$csvExport->open();
foreach ($orders as $order)
{
$csvExport->write($order);
}
$csvExport->close();
return;
}
It crashes if the file already exists, thus the unlink-command.
I want to convert a model query to json with json_encode, it doesn't work. But with a ordinary array it does.
$arr = array("one", "two", "three");
$data["json"] = json_encode($arr);
Output
<?php echo "var arr=".$json.";"; ?>
var arr=["one","two","three"];
But when I try to convert a query codeigniter throws an error. What is it with that?
This is the error message:
A PHP Error was encountered Severity:
Warning Message: [json]
(php_json_encode) type is unsupported,
encoded as null
And the converted "query" result = I mean model method is like this:
{"conn_id":null,"result_id":null,"result_array":[],"result_object":[],"current_row":0,"num_rows":9,"row_data":null}
I try to do like this
$posts = $this->Posts_model->SelectAll();
$data["posts"] = json_encode($posts);
By the way, the model and method works just fine when I do it without json_encode.
Something I'm propably doing wrong, but the question is what?
You appear to be trying to encode the CodeIgniter database result object rather than the result array. The database result object acts as a wrapper around the cursor into the result set. You should fetch the result array from the result object and then encode that.
Your model code appears to be something like this :
function SelectAll()
{
$sql = 'SELECT * FROM posts';
// Return the result object
return $this->db->query($sql);
}
It should be more like this :
function SelectAll()
{
$sql = 'SELECT * FROM posts';
$query = $this->db->query($sql);
// Fetch the result array from the result object and return it
return $query->result();
}
This will return an array of objects which you can encode in JSON.
The reason you are getting an error trying to encode the result object is because it has a resource member variable that cannot be encoded in JSON. This resource variable is actually the cursor into the result set.
public function lastActivity()
{
header("Content-Type: application/json");
$this->db->select('*');
$this->db->from('table_name');
$query = $this->db->get();
return json_encode($query->result());
}
As per latest CI standard use the following code in your controller file:
$this->output->set_content_type('application/json')->set_output(json_encode($arr));
Models (Post):
function SelectAll()
{
$this->db->select('*');
$this->db->from('post');
$query = $this->db->get();
return $query;
}
Controllers :
$data['post'] = $this->post->SelectAll()->result_array();
echo json_encode($data);
Result:
{"post":[{"id":"5","name":"name_of_post"}]}
Here is the working solution:
$json_data = $this->home_model->home_getall();
$arr = array();
foreach ($json_data as $results) {
$arr[] = array(
'id' => $results->id,
'text' => $results->name
);
}
//save data mysql data in json encode format
$data['select2data'] = json_encode($arr);