Skip to content

Commit ffb8761

Browse files
author
Radovan Janjic
committed
- Added: download output and possibility of fputs usage
1 parent 7d8bc3a commit ffb8761

File tree

2 files changed

+193
-73
lines changed

2 files changed

+193
-73
lines changed

MySQL_wrapper.class.php

Lines changed: 142 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/******************************************************************
33
*
44
* Projectname: PHP MySQL Wrapper Class
5-
* Version: 1.6
5+
* Version: 1.6.1
66
* Author: Radovan Janjic <[email protected]>
77
* Link: https://github.com/uzi88/PHP_MySQL_wrapper
88
* Last modified: 11 08 2014
@@ -35,7 +35,7 @@ class MySQL_wrapper {
3535
/** Class Version
3636
* @var float
3737
*/
38-
private $version = '1.6';
38+
private $version = '1.6.1';
3939

4040
/** Store the single instance
4141
* @var array
@@ -157,6 +157,16 @@ class MySQL_wrapper {
157157
*/
158158
private $REGEX = array('LIMIT' => '/limit[\s]+([\d]+[\s]*,[\s]*[\d]+[\s]*|[\d]+[\s]*)$/i', 'COLUMN' => '/^[a-z0-9_\-\s]+$/i');
159159

160+
/** Use MySQL SELECT ... INTO OUTFILE (Default: TRUE)
161+
* @var boolean
162+
*/
163+
private $attachment = FALSE;
164+
165+
/** Use MySQL SELECT ... INTO OUTFILE (Default: TRUE)
166+
* @var boolean
167+
*/
168+
public $mysqlOutFile = TRUE;
169+
160170
/** Singleton declaration
161171
* @param string $server - MySQL Host name
162172
* @param string $username - MySQL User
@@ -636,6 +646,11 @@ public function importUpdateCSV2Table($file, $table, $delimiter = ',', $enclosur
636646
* @return - File path
637647
*/
638648
public function exportTable2CSV($table, $file, $columns = '*', $where = NULL, $limit = 0, $delimiter = ',', $enclosure = '"', $escape = '\\', $newLine = '\n', $showColumns = TRUE) {
649+
// Without OUTFILE or as attachment
650+
if ($this->attachment || !$this->mysqlOutFile) {
651+
return $this->query2CSV("SELECT * FROM `$table`" . ($where ? " WHERE {$where}" : NULL) . ($limit ? " LIMIT {$limit}" : NULL), $file, $delimiter, $enclosure, $escape, $newLine, $showColumns);
652+
}
653+
639654
$fh = fopen($file, 'w') or $this->error("ERROR", "Can't create CSV file: {$file}");
640655
if (!$fh) {
641656
return FALSE;
@@ -676,6 +691,15 @@ public function exportTable2CSV($table, $file, $columns = '*', $where = NULL, $l
676691
return ($this->query($sql)) ? $file : FALSE;
677692
}
678693

694+
/** Set attachment var and return object.
695+
* @param void
696+
* @return - obj
697+
*/
698+
function attachment() {
699+
$this->attachment = TRUE;
700+
return $this;
701+
}
702+
679703
/** Export query to CSV file.
680704
* @param string $sql - MySQL Query
681705
* @param string $file - CSV File path
@@ -687,13 +711,50 @@ public function exportTable2CSV($table, $file, $columns = '*', $where = NULL, $l
687711
* @return - File path
688712
*/
689713
public function query2CSV($sql, $file, $delimiter = ',', $enclosure = '"', $escape = '\\', $newLine = '\n', $showColumns = TRUE) {
714+
// Without OUTFILE or as attachment
715+
if ($this->attachment || !$this->mysqlOutFile) {
716+
// Do query
717+
$this->query($sql);
718+
if ($this->affected > 0) {
719+
$fh = fopen($this->attachment ? 'php://output' : $file, 'w') or $this->error("ERROR", "Can't create CSV file: {$file}");
720+
if ($fh) {
721+
if ($this->attachment) {
722+
// Send response headers
723+
header('Content-Type: text/csv');
724+
header('Content-Disposition: attachment; filename="' . basename($file));
725+
header('Pragma: no-cache');
726+
header('Expires: 0');
727+
$this->attachment = FALSE;
728+
}
729+
$header = FALSE;
730+
while ($row = $this->fetchArray()) {
731+
// CSV header / field names
732+
if ($showColumns && !$header) {
733+
fputcsv($fh, array_keys($row), $delimiter, $enclosure);
734+
$header = TRUE;
735+
}
736+
fputcsv($fh, array_values($row), $delimiter, $enclosure);
737+
}
738+
fclose($fh);
739+
return $this->affected;
740+
} else {
741+
return FALSE;
742+
}
743+
} else {
744+
// No records
745+
return 0;
746+
}
747+
}
748+
749+
// Check if location is writable and unlink
690750
$fh = fopen($file, 'w') or $this->error("ERROR", "Can't create CSV file: {$file}");
691751
if (!$fh) {
692752
return FALSE;
693753
}
694754
fclose($fh);
695755
$file = realpath($file);
696756
unlink($file);
757+
697758
// Remove ; from end of query
698759
$sql = trim(rtrim(trim($sql), ';'));
699760
// Prepare SQL for column names
@@ -722,6 +783,85 @@ public function query2CSV($sql, $file, $delimiter = ',', $enclosure = '"', $esca
722783
return ($this->query($sql)) ? $file : FALSE;
723784
}
724785

786+
/** Export query to XML file or return as XML string
787+
* @param string $query - mysql query
788+
* @param string $rootElementName - root element name
789+
* @param string $childElementName - child element name
790+
* @return string - XML
791+
*/
792+
public function query2XML($query, $rootElementName, $childElementName, $file = NULL) {
793+
// Save to file or attachment
794+
if ($this->attachment || !empty($file)) { //echo $file; exit;
795+
$fh = fopen($this->attachment ? 'php://output' : $file, 'w') or $this->error("ERROR", "Can't create XML file: {$file}");
796+
if (!$fh) {
797+
return FALSE;
798+
} elseif ($this->attachment) {
799+
// Send response headers
800+
header('Content-Type: text/xml');
801+
header('Content-Disposition: attachment; filename="' . basename($file));
802+
header('Pragma: no-cache');
803+
header('Expires: 0');
804+
$this->attachment = FALSE;
805+
} else {
806+
$file = realpath($file);
807+
}
808+
$saveToFile = TRUE;
809+
} else {
810+
$saveToFile = FALSE;
811+
}
812+
813+
// Do query
814+
$r = $this->query($query);
815+
816+
// XML header
817+
if ($saveToFile) {
818+
fputs($fh, "<?xml version=\"1.0\" encoding=\"" . strtoupper($this->charset) . "\" ?>" . PHP_EOL . "<{$rootElementName}>" . PHP_EOL);
819+
} else {
820+
$xml = "<?xml version=\"1.0\" encoding=\"" . strtoupper($this->charset) . "\" ?>" . PHP_EOL;
821+
$xml .= "<{$rootElementName}>" . PHP_EOL;
822+
}
823+
824+
// Query rows
825+
while ($row = $this->call('fetch_object', $r)) {
826+
// Create the first child element
827+
$record = "\t<{$childElementName}>" . PHP_EOL;
828+
for ($i = 0; $i < $this->call('num_fields', $r); $i++) {
829+
// Different methods of getting field name for mysql and mysqli
830+
if ($this->extension == 'mysql') {
831+
$fieldName = $this->call('field_name', $r, $i);
832+
} elseif ($this->extension == 'mysqli') {
833+
$colObj = $this->call('fetch_field_direct', $r, $i);
834+
$fieldName = $colObj->name;
835+
}
836+
// The child will take the name of the result column name
837+
$record .= "\t\t<{$fieldName}>";
838+
// Set empty columns with NULL and escape XML entities
839+
if (!empty($row->$fieldName)) {
840+
$record .= htmlspecialchars($row->$fieldName, ENT_XML1);
841+
} else {
842+
$record .= NULL;
843+
}
844+
$record .= "</{$fieldName}>" . PHP_EOL;
845+
}
846+
$record .= "\t</{$childElementName}>" . PHP_EOL;
847+
if ($saveToFile) {
848+
fputs($fh, $record);
849+
} else {
850+
$xml .= $record;
851+
}
852+
}
853+
854+
// Output
855+
if ($saveToFile) {
856+
fputs($fh, "</{$rootElementName}>" . PHP_EOL);
857+
fclose($fh);
858+
return TRUE;
859+
} else {
860+
$xml .= "</{$rootElementName}>" . PHP_EOL;
861+
return $xml;
862+
}
863+
}
864+
725865
/** Create table from CSV file and imports CSV data to Table with possibility to update rows while import.
726866
* @param string $file - CSV File path
727867
* @param string $table - Table name
@@ -876,78 +1016,7 @@ public function nextAutoIncrement($table) {
8761016
public function deleteRow($table, $where = NULL, $limit = 0) {
8771017
return $this->query("DELETE FROM `{$table}`" . ($where ? " WHERE {$where}" : NULL) . ($limit ? " LIMIT {$limit}" : NULL) . ";") ? $this->affected : FALSE;
8781018
}
879-
880-
/** Export query to XML file or return as XML string
881-
* @param string $query - mysql query
882-
* @param string $rootElementName - root element name
883-
* @param string $childElementName - child element name
884-
* @return string - XML
885-
*/
886-
public function query2XML($query, $rootElementName, $childElementName, $file = NULL) {
887-
// Save to file
888-
if (!empty($file)) {
889-
$fh = fopen($file, 'w') or $this->error("ERROR", "Can't create XML file: {$file}");
890-
if (!$fh) {
891-
return FALSE;
892-
}
893-
fclose($fh);
894-
$file = realpath($file);
895-
$saveToFile = TRUE;
896-
} else {
897-
$saveToFile = FALSE;
898-
}
899-
900-
// Do query
901-
$r = $this->query($query);
902-
903-
// XML header
904-
if ($saveToFile) {
905-
file_put_contents($file, "<?xml version=\"1.0\" encoding=\"" . strtoupper($this->charset) . "\" ?>" . PHP_EOL . "<{$rootElementName}>" . PHP_EOL, LOCK_EX);
906-
} else {
907-
$xml = "<?xml version=\"1.0\" encoding=\"" . strtoupper($this->charset) . "\" ?>" . PHP_EOL;
908-
$xml .= "<{$rootElementName}>" . PHP_EOL;
909-
}
910-
911-
// Query rows
912-
while ($row = $this->call('fetch_object', $r)) {
913-
// Create the first child element
914-
$record = "\t<{$childElementName}>" . PHP_EOL;
915-
for ($i = 0; $i < $this->call('num_fields', $r); $i++) {
916-
// Different methods of getting field name for mysql and mysqli
917-
if ($this->extension == 'mysql') {
918-
$fieldName = $this->call('field_name', $r, $i);
919-
} elseif ($this->extension == 'mysqli') {
920-
$colObj = $this->call('fetch_field_direct', $r, $i);
921-
$fieldName = $colObj->name;
922-
}
923-
// The child will take the name of the result column name
924-
$record .= "\t\t<{$fieldName}>";
925-
// Set empty columns with NULL and escape XML entities
926-
if (!empty($row->$fieldName)) {
927-
$record .= htmlspecialchars($row->$fieldName, ENT_XML1);
928-
} else {
929-
$record .= NULL;
930-
}
931-
$record .= "</{$fieldName}>" . PHP_EOL;
932-
}
933-
$record .= "\t</{$childElementName}>" . PHP_EOL;
934-
if ($saveToFile) {
935-
file_put_contents($file, $record, FILE_APPEND | LOCK_EX);
936-
} else {
937-
$xml .= $record;
938-
}
939-
}
9401019

941-
// Output
942-
if ($saveToFile) {
943-
file_put_contents($file, "</{$rootElementName}>" . PHP_EOL, FILE_APPEND | LOCK_EX);
944-
return TRUE;
945-
} else {
946-
$xml .= "</{$rootElementName}>" . PHP_EOL;
947-
return $xml;
948-
}
949-
}
950-
9511020
/** Replace all occurrences of the search string with the replacement string in MySQL Table Column(s).
9521021
* @param string $table - Table name or "*" to replace in whole db
9531022
* @param mixed $columns - Search & Replace affected Table columns. An array may be used to designate multiple replacements.

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ This class implements a generic MySQL database access wrapper.
2525
* [Operations with CSV files](#operations-with-csv-files)
2626
* [Export table to CSV](#export-table-to-csv)
2727
* [Export query to CSV](#export-query-to-csv)
28+
* [Export table / export query to CSV using fputcsv](#export-table-export-query-to-csv-using-fputcsv)
29+
* [Download CSV file from query](#download-csv-file-from-query)
2830
* [Import CSV to Table](#import-csv-to-table)
2931
* [Import and update CSV to Table](#import-and-update-csv-to-table)
3032
* [Create table from CSV file](#create-table-from-csv-file)
3133
* [Operations with XML files](#operations-with-xml-files)
3234
* [Export query to XML](#export-query-to-xml)
35+
* [Download XML file from query](#download-xml-file-from-query)
3336
* [Do str_replace in given database, table or defined columns in table](#string-search-and-replace-in-all-or-defined-table-columns)
3437
* [Search string & replace string](#string-search-and-replace-in-all-or-defined-table-columns)
3538
* [Search array & replace string](#string-search-and-replace-in-all-or-defined-table-columns)
@@ -656,6 +659,40 @@ $path = $db->query2CSV('select * from `table` limit 2,2', 'test_files/test-query
656659
$db->close();
657660
```
658661

662+
#### Export table / export query to CSV using fputcsv
663+
```php
664+
$db = MySQL_wrapper::getInstance(MySQL_HOST, MySQL_USER, MySQL_PASS, MySQL_DB);
665+
666+
// Connect
667+
$db->connect();
668+
669+
// Don't use mysql outfile
670+
$db->mysqlOutFile = FALSE;
671+
672+
// Table to CSV
673+
$db->exportTable2CSV('table', 'test_files/test-1.txt');
674+
675+
// Query to CSV
676+
$path = $db->query2CSV('select * from `table` limit 10', 'test_files/test-query2csv.csv');
677+
678+
// Close connection
679+
$db->close();
680+
```
681+
682+
#### Download CSV file from query
683+
```php
684+
$db = MySQL_wrapper::getInstance(MySQL_HOST, MySQL_USER, MySQL_PASS, MySQL_DB);
685+
686+
// Connect
687+
$db->connect();
688+
689+
// Set as attachment and execute
690+
$db->attachment()->query2CSV('select * from `table`', 'test.csv');
691+
692+
// Close connection
693+
$db->close();
694+
```
695+
659696
#### Import CSV to Table
660697
```php
661698
$db = MySQL_wrapper::getInstance(MySQL_HOST, MySQL_USER, MySQL_PASS, MySQL_DB);
@@ -778,6 +815,20 @@ $xml = $db->query2XML('select * from `table` limit 10', 'items', 'item');
778815
$db->close();
779816
```
780817

818+
#### Download XML file from query
819+
```php
820+
$db = MySQL_wrapper::getInstance(MySQL_HOST, MySQL_USER, MySQL_PASS, MySQL_DB);
821+
822+
// Connect
823+
$db->connect();
824+
825+
// Set as attachment and execute
826+
$db->attachment()->query2XML('select * from `table`', 'root', 'item', 'test.xml');
827+
828+
// Close connection
829+
$db->close();
830+
```
831+
781832
### Transactions
782833
```php
783834
$db = MySQL_wrapper::getInstance(MySQL_HOST, MySQL_USER, MySQL_PASS, MySQL_DB);

0 commit comments

Comments
 (0)