Here's my current code:
$link = mysqli_connect("localhost", "username", "password", "database");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT id, title FROM titles WHERE type = 'movie' ORDER BY id ASC";
if ($result = mysqli_query($link, $query)) {
while ($row = mysqli_fetch_assoc($result)) {
printf ("%s-%s\n", $row["id"], $row["title"]);
}
mysqli_free_result($result);
}
mysqli_close($link);
Using printf is correctly printing all the rows from my MySQL table.
However, instead of printing it, I want to write it to a text file. Is this possible to do with printf or should I be doing something else?
if you want to write it to the disk, on the server, you should look into fopen(), fwrite() and fclose()
also you could use file_put_contents, but that would require you to prepare all the content before writing it to the file (which could lead to high memory usage if you have lots of records) or if you go with the "append" mode, writing 1 line at a time, you'll have all the overhead of opening and closing the file each time
if you want to make the browser download it, instead of just showing the content, then you need to add a header to the response
header('Content-Disposition: attachment; filename="'.$filename.'"');
preferably adding some content type before it. for example, in your case:
header('Content-type: text/plain');
fprintf used to write to the file file_put_contents also works
$fp = fopen('output.txt', 'w');
$in = 'text';
fprintf($fp, '%s', $in);
Use fprintf(). It works just like printf(), but prints to a file stream.
if ($result = mysqli_query($link, $query)) {
if ($fp = fopen("filename.txt", "w")) {
while ($row = mysqli_fetch_assoc($result)) {
fprintf ($fp, "%s-%s\n", $row["id"], $row["title"]);
}
fclose($fp);
}
mysqli_free_result($result);
}
Related
I am using the below for csv export but i want to export as a pipe delimeted output text file format.
My code generates a txt file using PHP's fputcsv function.
For the delimiter, I am trying to use '|'.
this mycode:
function to_CSV($table) {
$file_csv = "file_csv.csv";
$fp = fopen('php://output', 'w');
$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='htmltable' AND TABLE_NAME='$table'";
$result = mysqli_query(db_connect(),$query);
while ($row = mysqli_fetch_row($result)) {
$header[] = $row[0];
}
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename='.$file_csv);
fputcsv($fp, $header);
$query ="SELECT * from $table";
$result = mysqli_query(db_connect(),$query);
while($row = mysqli_fetch_row($result)) {
fputcsv($fp, $row);
}
exit;
}
fclose($fp);
$contents = file_get_contents($file_csv);
$contents = str_replace(",", "|", $contents);
file_put_contents($file_csv, $contents);
How to implementation in codeigniter. help me out please.
thanks a lot.
according to the docs fputcsv format line as CSV and write to file pointer, it has a third parameter which expects a delimiter - take a look at
https://www.php.net/manual/en/function.fputcsv
In your case it means
while($row = mysqli_fetch_row($result)) {
fputcsv($fp, $row, '|');
}
however the main question is - if you use Codeigniter as underlying Framework - why dont you use the model principle and aside of that the provided query builder? - it will make your life much easier.
You can find more informations in their very well written documentation. Take a look at https://codeigniter.com/user_guide/general/models.html?highlight=model
I am trying to write some code that grabs a CSV file pulls the relevant postcode column then looks up that postcode in a MySql database which has longitude and latitude fields then save them to an XML file so it can be used in a different program
I think this code piece is all working, but for some reason, it only outputs the last field of the query :
//Open the file.
$fileHandle = fopen("test.csv", "r");
$postcode = array();
while (($row = fgetcsv($fileHandle, 0, ",")) !== FALSE) {
array_push($postcode, $row[40]);
}
$postcodefil = (array_unique($postcode));
$postcodefil = str_replace(' ', '', $postcodefil);
$postcodefil = preg_replace('/\s+/', '', $postcodefil);
//print_r($postcodefil);
foreach ($postcodefil as $value) {
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT postcode, latitude, longitude FROM postcode WHERE postcode='$value' ";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$myfile = fopen("test.xml", "w") or die("Unable to open file!");
$lat = $row["latitude"];
$lng = $row["longitude"];
fwrite($myfile, $lat."testss".$lng."\n");
echo $lat;
echo $lng;
echo "<br />";
}}
} // end of foreach
$conn->close();
however when i run it, it echo's correctly
50.822398-0.139938
51.444908-1.295341
50.841951-0.842508
51.308504-0.551835
etc.... etc...
but the Fwrite just outputs the last line
51.120916testss-0.599545
I' m totally confused by this. Please forgive me if it's something basic that I've over looked and thanks in advance.
The problem is that you open the file in each loop, this overwrites the previous data...
$myfile = fopen("test.xml", "w") or die("Unable to open file!");
while($row = $result->fetch_assoc()) {
So move the open outside the loop.
The second issue is that you aren't writing XML at all. You need to do something like...
$xml = simplexml_load_string("<coords />");
while($row = $result->fetch_assoc()) {
$newCoord = $xml->addChild("coord");
$newCoord->addChild("latitude", $row["latitude"]);
$newCoord->addChild("longitude", $row["longitude"]);
}
$xml->saveXML("test.xml");
This will generate a simple XML file, you will need to set the element names as appropriate.
First thing put the connection outside of the foreach loop, and the fopen outside the while
loop.
You open the xml file in the 'w' mode means according to the doc
Open for writing only; place the file pointer at the beginning of the
file and truncate the file to zero length. If the file does not exist,
attempt to create it.
You need append mode 'a'
Open for writing only; place the file pointer at the end of the file.
If the file does not exist, attempt to create it. In this mode,
fseek() has no effect, writes are always appended.
This will work for you. But you still making a db request per postalcode, i would suggest to collect all the postal code you need to query and make one db request to database with sql IN operator.
I'm having a problem writing the results of a MySQL query to a file using php. There are definitely results from the search, and the file is created, but when you open the file it's empty. I think it's something to do with how I'm writing to the file, but I'm not sure.
$result = mysql_query($compsel);
if(!result) die("unable to process query: " . mysql_error());
$fp = fopen('results.csv','w');
mysql_data_seek($result,0); //set data pointer to 0
$rw = mysql_fetch_array($result, MYSQL_ASSOC);
print_r($rw);
foreach ($rw as $fields){
fputcsv($fp, $fields);
}
fclose($fp);
Thanks in advance!
Here's an example:
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// output the column headings
fputcsv($output, array('Column 1', 'Column 2', 'Column 3'));
// fetch the data
mysql_connect('localhost', 'username', 'password');
mysql_select_db('database');
$rows = mysql_query('SELECT field1,field2,field3 FROM table');
// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows)) fputcsv($output, $row);
You can modify it to suit your needs.
Source: http://code.stephenmorley.org/php/creating-downloadable-csv-files/
I have this piece of PHP code that's intended to retrieve data from a mySQL database, and export it to a CSV file that has to be automatically downloaded after it was created.
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
// fetch mysql table rows
$sql = "select * from users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
$fp = fopen('users.csv', 'w');
while($row = mysqli_fetch_assoc($result)) {
fputcsv($fp, $row);
}
fclose($fp);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
mysqli_close($connection);
The problem here is that it:
Retrieves the data.
Retrieves the CSV file on the server in the same directory of the export.php file with the data on it.
Downloads the file with the same name BUT it's EMPTY
Thanks.
You're writing it to a file called users.csv, but the file you are forcing the user to download is the output of the page.
As long as your query is correct, once the PHP script has run, there should be a file called users.csv in the same directory as the PHP file that contains the correct data.
You need to output the data to the browser for it to be attributed to the file you're downloading.
Try this:
//Connect to database
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
//Fetch mysql table rows
$sql = "select * from users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
//Close connection
mysqli_close($connection);
//Set $output
$output = "";
//Set header values
$headers = array("Header 1", "Header 2", "Header 3");
//Insert header values to $output
foreach($headers as $h){
$output .= fieldCheck($h) . ",";
}
$output = rtrim($output, ","). "\n";
//Iterate through results
while($row = mysqli_fetch_assoc($result)) {
foreach($row as $cell){
//Comma-separate each value
$output .= fieldCheck($cell).",";
}
//Remove last comma of each line and add newline
$output = rtrim($output, ",") . "\n";
}
//Set headers
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
//Output
echo $output;
exit;
//Function in case of comma in field
function fieldCheck($string){
if(strpos($string, ",") !== false){
$string = '"'.$string.'"';
}
return $string;
}
I have seen this question come up quite a few times and here the user is sending the data to "users.csv" as shown below:
$fp = fopen('users.csv', 'w');
The issue is that unless the file "users.csv" is already created there is nothing to write the data to, so the CSV is blank. The "fopen" does not create the file it only opens an existing file and the "w" directive then instructs "fputcsv" to put it into the file "users.csv" which may not exist and if the file does exist it writes over the existing file.
Here is an explainer PHP script that will send the output (CSV) to a filename of your choice for downloading:
//Connect to database
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
//Get the data
//The order and number of elements must match the header below or the data
//will appear in the wrong columns.
$sql = "SELECT FirstName,LastName,Address,City,State,Zip FROM users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
//Close connection
mysqli_close($connection);
//Name of the file you want the user to download can be any name but
//use the .CSV file extension so it will be recognized
//as a CSV when downloaded.
$NameOfCSVFileToDownload = "MyCSVFile.csv";
//set headers tells the page what to do
header("Content-Type: application/csv; charset=utf-8");
header("Content-Disposition: attachment;filename=\"$NameOfCSVFileToDownload\"");
//Where to send the data -
//there are several option but sending it to output will insert
//the data into "$NameOfCSVFileToDownload" when complete, your output.
//Output is a way to access I/O streams
$output = fopen("php://output", 'w');
//Add the header or 1st row for your data
//-notice we are sending it to "$output" you can add any names you want
//for this header row but make sure that the number of columns in the header
//matches the number of columns you are retrieving from the database or they
//will not line up when you open up the CSV and things will look scrambled.
fputcsv($output, array('FirstName','LastName','Address','City','State','Zip'));
//Loop through the data and insert the data into "$output"
while($rows = $result->fetch_assoc()){
fputcsv($output, $rows);
}
//Close the "$output" file to complete the write.
fclose($output);
That's all, call the page and it will prompt to open or download the CSV that contains data. If it is still blank make sure your SQL statement is actually pulling data.
You can also review the PHP manual on streams to better understand.
PHP Manual
Combining a few ideas mentioned in the comments:
Output directly to stdout (rather than a users.csv file). This prevents concurrent processes from clashing with the same output file. No need to buffer temporary results in a variable, either.
Use fputcsv()'s 3rd argument to specify ';' as the field separator. No need to rewrite special code for that.
Use array_map() and a custom filter to add quotes around all the fields.
// Helper function to surround a string with double quotes
function pad_with_quotes($s) {
return '"' . $s . '"';
}
// Helper function to output a row to $fp:
function output_row($fp, $row) {
// Separate fields with ';':
fputcsv($fp, array_map('pad_with_quotes', $row), ';');
}
// Send HTTP headers
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
// Open a pointer to stdout:
$fp = fopen('php://output', 'w'); // TO DO: check for fopen() failure
// Output headers (padded with quotes):
output_row($fp, ['foo', 'bar']); // TO DO: change headers
// DB connection/query goes here; omitted for brevity
// Loop through DB results:
while($row = mysqli_fetch_assoc($result)) {
// Output a row of results:
output_row($fp, row);
}
I am trying to pull out data from my database using php and exporting it into a downloadable CSV file that can be opened with excel. I am able to do this when i use mysql however, many have advised to not include mysql syntax in my code as its being deprecated and instead i should use mysqli. I have changed my code but now my code is not working. Does anyone know why that is?
mysql version (working version)`
mysql_connect('localhost', 'xxxxx', 'xxxxx') or die('connect');
mysql_select_db('db') or die('select');
$result = mysql_query('SELECT * bodyshops_master_network') or die('query');
if(mysql_num_rows($result) == 0)
{
die('no data');
}
$fh = tmpfile() or die('tmpfile');
$cols = array_keys(mysql_fetch_assoc($result));
fputcsv($fh, $cols);
mysql_data_seek($result, 0); // set result row pointer back to first row
while($row = mysql_fetch_assoc($result))
{
fputcsv($fh, $row);
}
rewind($fh);
$text = fread($fh, 999999);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="download.csv"');
header('Content-Length: ' . strlen($text));
echo $text;
exit;
mysqli version (not working):
$mysqli = new mysqli("localhost", "xxxxx", "xxxxx", "db");
if (mysqli_connect_errno())
{
printf("Connect failed: ", mysqli_connect_error());
exit();
} else
{
$result = "SELECT * FROM bodyshops_master_network";
if(mysqli_num_rows($result) == 0)
{
die('no data');
}
$fh = tmpfile() or die('tmpfile');
$cols = array_keys($result->fetch_assoc());
fputcsv($fh, $cols);
$result->data_seek(0); // set result row pointer back to first row
while($row = $result->fetch_assoc())
{
fputcsv($fh, $row);
}
rewind($fh);
$text = fread($fh, 999999);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="download.csv"');
header('Content-Length: ' . strlen($text));
echo $text;
exit;
Check phpinfo to see that mysqli extension is enabled.
Remove/comment the header calls so that you receive the output as plain HTML so that you notice if any message shows up (due to die or coding error) or if you actually get the data.
Also note that you loose the date of the first record you retrieve because you call:
$cols = array_keys(mysql_fetch_assoc($result));
respectively
$cols = array_keys($result->fetch_assoc());
What is not working?
Are you getting any errors?
Is the file empty, is there any file downloading?
Maybe errors aren't enabled, try this:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
I'm new on StackOverflow, I think this would help. (I speak spanish, I hope you to understand my english :D )
I've been looking for a simply way to use mysqli and download a csv file that could be read by excel without UTF-8 problems (using ñ,á,ü...). I didn't found it, so I created one by myself (learning from Google and StackOverflow answers), after some hours I got something that works finally.
This is a Class that connects with the database and the functions will do whatever you want using mysqli and PHP. In this case, calling this class (require or include), just use the "downloadCsv()" function.
As an example, this would be the "class.php" file:
<?php
class DB{
private $con;
//this constructor connects with the database
public function __construct(){
$this->con = new mysqli("Your_Host","Your_User","Your_Pass","Your_DatabaseName");
if($this->con->connect_errno > 0){
die('There was a problem [' . $con->connect_error . ']');
}
}
//create the function that will download a csv file from a mysqli query
public function downloadCsv(){
$count = 0;
$header = "";
$data = "";
//query
$result = $this->con->query("SELECT * FROM Your_TableName");
//count fields
$count = $result->field_count;
//columns names
$names = $result->fetch_fields();
//put column names into header
foreach($names as $value) {
$header .= $value->name.";";
}
}
//put rows from your query
while($row = $result->fetch_row()) {
$line = '';
foreach($row as $value) {
if(!isset($value) || $value == "") {
$value = ";"; //in this case, ";" separates columns
} else {
$value = str_replace('"', '""', $value);
$value = '"' . $value . '"' . ";"; //if you change the separator before, change this ";" too
}
$line .= $value;
} //end foreach
$data .= trim($line)."\n";
} //end while
//avoiding problems with data that includes "\r"
$data = str_replace("\r", "", $data);
//if empty query
if ($data == "") {
$data = "\nno matching records found\n";
}
$count = $result->field_count;
//Download csv file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=FILENAME.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo $header."\n".$data."\n";
}
?>
After creating the "class.php" file, in this example, use that function on "download.php" file:
<?php
//call the "class.php" file
require_once 'class.php';
//instantiate DB class
$export = new DB();
//call function
$export->downloadCsv();
?>
After download, open the file with MS Excel.
I hope this help you, I think I wrote it well, I didn't feel comfortable with the text and code field.