So I have this PHP-script which is linked to a contact form on one of my clients sites. What the PHP-script does is basically to take all the fields and values and generates a .txt file with the information given in the form. After that the script decides what to name the file depending on what information you add in the field 'forefternamn'.
My question is pretty straight forward. How do I, instead of naming the file after the field, name it with a serial number?
I would like the serial number to start with 1000 on the first submit, then I would just like it to keep going with 1001, 1002, 1003, 1004, etc..
So the files would look like this:
1000.txt
1001.txt
1002.txt
1003.txt
1004.txt
etc...
This is the PHP-script I'm using:
<?php
$nyckel = array(
'privatforetag',
'forefternamn',
'foretagsnamn',
'gatuadress',
'mobil',
'telefon',
'e-post',
'epost',
'kalender-tidig',
'kalender-senast',
'flyttar-fran-gatuadress',
'flyttar-fran-portkod',
'flyttar-fran-postadress',
'boendetyp',
'meter',
'hiss',
'flyttar-till-gatuadress',
'flyttar-till-postnummer',
'flyttar-till-portkod',
'boendetyp2',
'meter2',
'hiss2',
'rum',
'personer',
'kontor',
'moblerat',
'boyta',
'biyta',
'inventarielista',
'packning',
'uppackning',
'inventarie',
'antalflyttlador',
'flyttlada',
'miljostation',
'flyttstad',
'magasinering',
'student',
'ovriginfo',
'rekommenderad',
'hurhittade'
);
foreach ($nyckel as $key) {
if ($_POST[$key]) {
$input .= $_POST[$key]. "\t";
} else {
$input .= "-\t";
}
$thekey .= $key. "\t";
}
$index = 1;
$name = str_replace(" " , "" , $_POST["forefternamn"]);
$filename = $name . $index . ".txt";
while (file_exists($filename)) {
$index++;
$filename = $name .$index. ".txt";
}
$handle = fopen($filename, 'w') or die('Cannot open file: '.$filename);
fwrite($handle, $thekey);
fwrite($handle, PHP_EOL);
fwrite($handle, $input);
fclose($handle);
if (file_exists($filename)) {
echo "<script>window.location = 'www.domain.com'</script>";
}?>
Create a database table with a primary key ID field and a name field. Insert the name into the table and retrieve the generated ID. Use this generated ID to name the file.
How about something like:-
$dir='c:/temp/inv/';
$col=glob( $dir . '*.txt' );
$tmp=array();
foreach( $col as $file ) $tmp[]=intval( pathinfo( $file, PATHINFO_FILENAME ) );
$last=intval( max( $tmp ) );
$next=( $last+1 ).'.txt';
echo $next;
To continue the idea as requested, and to keep in line with the 'racy' ? comment... how about:-
$nyckel = array(
'privatforetag',
'forefternamn',
'foretagsnamn',
/* rest of the elements removed for brevity */
'student',
'ovriginfo',
'rekommenderad',
'hurhittade'
);
/* Helper function to generate next invoice id */
function getnextinvid( $path=false ){
if( $path ){
$col=glob( $path . '*.txt' );
$tmp=array();
foreach( $col as $file ) $tmp[]=intval( pathinfo( $file, PATHINFO_FILENAME ) );
$last=intval( max( $tmp ) );
return $path . ( $last+1 ).'.txt';
}
return false;
}
/* Loop through array to get POSTed values */
$thekey=$input=array();
foreach( $nyckel as $key ) {
$input[]=isset( $_POST[ $key ] ) ? $_POST[ $key ] : '-';
$thekey[]=$key;
}
/* The output filename / invoice should be sequentially numbered */
$output=getnextinvid('c:/temp/inv/');
if( $output ) {
/* write your data to the output file */
$bytes=file_put_contents( $output, implode( "\t", $thekey ) . PHP_EOL . implode( "\t", $input ), FILE_TEXT );
/* Does the new invoice exist? */
$exists=file_exists( $output ) ? true : false;
/* good practice to call this after calls to certain functions */
clearstatcache();
/* Redirect - alternatively use javascript as originally */
if( $exists && $bytes ) header('location: http://www.domain.com');
} else {
echo 'failed';
}
Related
I have written a php script for download excel file which contain some MySQL data fetching by a MySQL query. Data is coming correctly but the field names on the top row are showing in one row with commas. I want single field name in single column. what I am missing in the code. Please If anyone have any idea how to achieve that. Here is my code:
<?php
include('connection.php');
$header = '';
$data = '';
$select = "select * from pdbp inner join bp on(pdbp.bp_id=bp.id)";
//run mysql query and then count number of fields
$export = mysql_query ( $select )
or die ( "Sql error : " . mysql_error( ) );
$fields = mysql_num_fields ( $export );
//create csv header row, to contain table headers
//with database field names
for ( $i = 0; $i < $fields; $i++ ) {
$header .= mysql_field_name( $export , $i ) . ",";
}
//this is where most of the work is done.
//Loop through the query results, and create
//a row for each
while( $row = mysql_fetch_row( $export ) ) {
$line = '';
//for each field in the row
foreach( $row as $value ) {
//if null, create blank field
if ( ( !isset( $value ) ) || ( $value == "" ) ){
$value = "\t";
}
//else, assign field value to our data
else {
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . "\t";
}
//add this field value to our row
$line .= $value;
}
//trim whitespace from each row
$data .= trim( $line ) . "\n";
}
//remove all carriage returns from the data
$data = str_replace( "\r" , "" , $data );
$file_name = 'excel_data';
//create a file and send to browser for user to download
header("Content-type: application/vnd.ms-excel");
header( "Content-disposition: filename=".$file_name.".xls");
print "$header\n$data";
exit;
?>
I am attempting to get data from 3 separate CSVs and put the data into 3 separate arrays, in the code below the first 2 work fine, the third which is a clone of the second one with a few details changed doesn't... why?
How can I do get the third working too?
// First one
$awd_fp = fopen( 'https://example.com/test1.csv', 'r' );
$awd_stocks_temp = array();
while( $awd_row = fgetcsv( $awd_fp ) ) {
$awd_stocks_temp[] = $awd_row;
}
fclose( $awd_fp );
// Second one
$aeo_fp = fopen( 'https://example.com/test2.csv', 'r' );
$aeo_stocks_temp = array();
while( $aeo_row = fgetcsv( $aeo_fp ) ) {
$aeo_stocks_temp[] = $aeo_row;
}
fclose( $aeo_fp );
// Third one
$hb_fp = fopen( 'https://example.com/test3.csv', 'r' );
$hb_stocks_temp = array();
while( $hb_row = fgetcsv( $hb_fp ) ) {
$hb_stocks_temp[] = $hb_row;
}
fclose( $hb_fp );
echo '<hr>';
echo count( $awd_stocks_temp ) . ' / ';
echo count( $aeo_stocks_temp ) . '/ ';
echo count( $hb_stocks_temp );
echo '<hr>';
Your code is working perfectly fine it seems something's wrong with your csv file. Only thing I would suggest is instead of writing same code for reading csv file why don't you loop through it.
<?php
$files = array(
'test1.csv',
'test2.csv',
'test3.csv'
);
$stocks_temp = array();
$ctr = 0;
foreach($files as $file){
$fp = fopen( $file, 'r' );
while( $row = fgetcsv( $fp ) ) {
$stocks_temp[$ctr][] = $row;
}
fclose( $fp );
$ctr++;
}
// you will get all data in multidimensional array
echo "<pre>";
print_r($stocks_temp);
?>
I am using parse_ini_file to parse an ini file using PHP.
Now I first upload an INI file to my server then open it and allow user to mak custom changes to the file.
Now once users has edited the file i get the data from post and save the file back to server. But Now i dont get my sections. INIdetails,Dialplan in the updated file so when i also want to write that to file how to do that?
This is the code :
$this->data['parameters'] = parse_ini_file($path.$filename,true);
/*Getting Our POST DATA from View*/
$data = array(
'SipUserName' => $this->input->post('SipUserName') ,
'SipAuthName' => $this->input->post('SipAuthName'),
'DisplayName' => $this->input->post('DisplayName'),
'Password' => $this->input->post('Password'),
'Domain' => $this->input->post('Domain'),
'Proxy' => $this->input->post('Proxy'),
'Port' => $this->input->post('Port'),
'ServerMode' => $this->input->post('ServerMode'),
'Param_1' => $this->input->post('Param_1'),
'Param_2' => $this->input->post('Param_2')
);
/*Creating New file with the name of customer loggedin*/
$name = $this->session->userdata('username');
$ext = $this->session->userdata('extension');
$custom_file = fopen('uploads/'.$name.'_'.$ext.'.ini', 'w');
fwrite($custom_file, "[INIDetails]\n");
foreach ($data as $key => $value)
{
fwrite($custom_file, " $key = $value\n");
}
fclose($custom_file);
/*Setting path to New CUSTOM file with customer name as prefix*/
$file = $path.$custom_file;
function write_php_ini($array, $file)
{
$res = array();
foreach($array as $key => $val)
{
if(is_array($val))
{
$res[] = "[$key]";
foreach($val as $skey => $sval) $res[] = "$skey = ".(is_numeric($sval) ? $sval : '"'.$sval.'"');
}
else $res[] = "$key = ".(is_numeric($val) ? $val : '"'.$val.'"');
}
safefilerewrite($file, implode("\r\n", $res));
}
function safefilerewrite($fileName, $dataToSave)
{ if ($fp = fopen($fileName, 'w'))
{
$startTime = microtime(TRUE);
do
{ $canWrite = flock($fp, LOCK_EX);
// If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load
if(!$canWrite) usleep(round(rand(0, 100)*1000));
} while ((!$canWrite)and((microtime(TRUE)-$startTime) < 5));
//file was locked so now we can store information
if ($canWrite)
{ fwrite($fp, $dataToSave);
flock($fp, LOCK_UN);
}
fclose($fp);
}
}
/*Creates ini file, dumps array to string and creates .INI file*/
write_php_ini($data,$file);
The culprit from your previous code is that your array is not formatted correctly, it should be array of arrays to achieve what you want.
Try below code:
// First read the ini file that the user was editing
// Your idea to read the existing ini file is good, since it will generate you the structured array
$previous_data = parse_ini_file($path . $filename, true);
// Overwrite/edit the previous_data using user's post data
$previous_data['INIDetails']['SipUserName'] = $this->input->post('SipUserName');
$previous_data['INIDetails']['Password'] = $this->input->post('Password');
$previous_data['INIDetails']['Domain'] = $this->input->post('Domain');
$previous_data['INIDetails']['Proxy'] = $this->input->post('Proxy');
$previous_data['INIDetails']['Port'] = $this->input->post('Port');
$previous_data['INIDetails']['SipAuthName'] = $this->input->post('SipAuthName');
$previous_data['INIDetails']['DisplayName'] = $this->input->post('DisplayName');
$previous_data['INIDetails']['ServerMode'] = $this->input->post('ServerMode');
$previous_data['INIDetails']['UCServer'] = $this->input->post('UCServer');
$previous_data['INIDetails']['UCUserName'] = $this->input->post('UCUserName');
$previous_data['INIDetails']['UCPassword'] = $this->input->post('UCPassword');
$previous_data['DialPlan']['DP_Exception'] = $this->input->post('DP_Exception');
$previous_data['DialPlan']['DP_Rule1'] = $this->input->post('DP_Rule1');
$previous_data['DialPlan']['DP_Rule2'] = $this->input->post('DP_Rule2');
$previous_data['DialPlan']['OperationMode'] = $this->input->post('OperationMode');
$previous_data['DialPlan']['MutePkey'] = $this->input->post('MutePkey');
$previous_data['DialPlan']['Codec'] = $this->input->post('Codec');
$previous_data['DialPlan']['PTime'] = $this->input->post('PTime');
$previous_data['DialPlan']['AudioMode'] = $this->input->post('AudioMode');
$previous_data['DialPlan']['SoftwareAEC'] = $this->input->post('SoftwareAEC');
$previous_data['DialPlan']['EchoTailLength'] = $this->input->post('EchoTailLength');
$previous_data['DialPlan']['PlaybackBuffer'] = $this->input->post('PlaybackBuffer');
$previous_data['DialPlan']['CaptureBuffer'] = $this->input->post('CaptureBuffer');
$previous_data['DialPlan']['JBPrefetchDelay'] = $this->input->post('JBPrefetchDelay');
$previous_data['DialPlan']['JBMaxDelay'] = $this->input->post('JBMaxDelay');
$previous_data['DialPlan']['SipToS'] = $this->input->post('SipToS');
$previous_data['DialPlan']['RTPToS'] = $this->input->post('RTPToS');
$previous_data['DialPlan']['LogLevel'] = $this->input->post('LogLevel');
// Set Name of New file with the name of customer logged in
$name = $this->session->userdata('username');
$ext = $this->session->userdata('extension');
$custom_file = "$name_$ext.ini";
$new_filename = $path . $custom_file;
// Write the INI file
write_php_ini($data, $new_filename);
function write_php_ini($array, $new_filename)
{
$res = array();
foreach ($array as $key => $val) {
if (is_array($val)) {
$res[] = "[$key]";
foreach ($val as $skey => $sval) {
$res[] = "$skey = " . (is_numeric($sval) ? $sval : '"' . $sval . '"');
}
} else {
$res[] = "$key = " . (is_numeric($val) ? $val : '"' . $val . '"');
}
}
safefilerewrite($new_filename, implode("\r\n", $res));
}
function safefilerewrite($new_filename, $dataToSave)
{
if ($fp = fopen($new_filename, 'w')) {
$startTime = microtime(true);
do {
$canWrite = flock($fp, LOCK_EX);
// If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load
if (!$canWrite) {
usleep(round(rand(0, 100) * 1000));
}
} while ((!$canWrite) and ((microtime(true) - $startTime) < 5));
//file was locked so now we can store information
if ($canWrite) {
fwrite($fp, $dataToSave);
flock($fp, LOCK_UN);
}
fclose($fp);
}
}
From your previous code, there are bunch of inappropriate codes which I remove. Also, too many inconsistencies like Method naming, variable naming etc.
If your function was named Camel cased then through out your code it must be named as camel-cased. If your variables are with underscore, then through out your code, they must have underscore for two or more worded variable.
I didn't edit the naming convention of your code so you won't be confused but i suggest to have a consistent naming convention through out your project.
UPDATED:
based on your answer, it seems like you changed your whole code. I would like to provide another way using nested foreach and passing by reference that save couple of lines:
$this->data['params'] = $this->parameter_m->get();
$this->data['parameters'] = parse_ini_file($path . $filename, true);
foreach ($this->data['parameters'] as $key_header => &$value_header) {
foreach ($value_header as $key_item => &$value_item) {
$value_item = $this->input->post($key_item);
}
}
$this->load->helper('file');
$this->load->library('ini');
$file = $path . $filename;
$ini = new INI($file);
$ini->read($file);
$ini->write($file, $this->data['parameters']);
Finally i got an answer:
I will loop through what i get from POST and will get each array's key. And then i will give the resultant to my Write Method
$this->data['params'] = $this->parameter_m->get();
/*Getting the parameters to display on view*/
$this->data['parameters'] = parse_ini_file($path.$filename,true);
while (current($this->data['parameters']) )
{
$param_set = current($this->data['parameters']);
$param_type = key($this->data['parameters']);
foreach ($param_set as $key =>$value)
{
$this->data['parameters'][$param_type][$key] = $this->input->post($key);
}
next($this->data['parameters']);
}
$this->load->helper('file');
$this->load->library('ini');
$file = $path.$filename;
$ini = new INI($file);
$ini->read($file);
$ini->write($file, $this->data['parameters']);
I need to export the data from the Mysql table “tblinfoaanvraag” (see here for picture of the table: http://s29.postimg.org/qeqp43z4n/mysql.png)
I have a working code with the correct query and it triggers an Excel download and the data is in the file. However, The data inside the Excel file is still formatted as an sql query result and the headers (field names) are only shown as “Array”.
So there are two things I’m struggling with at this point: format the sql-results as cells in the .csv file and the headers/table field names should be shown correctly instead of just “Array”.
Here is a screenshot of the downloaded Excel-file: http://s13.postimg.org/p0rcehehj/excel1.png
The code:
<?php
if(isset($_POST['InfoaanvragenDownloaden']))
{
try
{
// Variables for later use
$header="";
$data="";
//connection
$sHost = "localhost";
$sUser = "root";
$sPassword = "";
$sDatabase = "corbati";
$link = #mysqli_connect($sHost, $sUser, $sPassword, $sDatabase) or die("Oop, dbase is gone!");
//create query to select as data from your table
$select = "select * from tblinfoaanvraag ORDER BY PK_Infoaanvraag DESC";
//run mysql query and then count number of fields
$export = mysqli_query ( $link, $select )
or die ( "Sql error : " . mysql_error( ) );
$fields = mysqli_num_fields ( $export );
//create csv header row, to contain table headers
//with database field names
for ( $i = 0; $i < $fields; $i++ ) {
$header .= mysqli_fetch_fields( $export ) . ",";
}
//this is where most of the work is done.
//Loop through the query results, and create
//a row for each
while( $row = mysqli_fetch_row( $export ) ) {
$line = '';
//for each field in the row
foreach( $row as $value ) {
//if null, create blank field
if ( ( !isset( $value ) ) || ( $value == "" ) ){
$value = ",";
}
//else, assign field value to our data
else {
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . ",";
}
//add this field value to our row
$line .= $value;
}
//trim whitespace from each row
$data .= trim( $line ) . "\n";
}
//remove all carriage returns from the data
$data = str_replace( "\r" , "" , $data );
//create a file and send to browser for user to download
header("Content-type: application/vnd.ms-excel");
header( "Content-disposition: filename=Infoaanvragen.csv");
print "$header\n$data";
exit;
}
catch (Exception $e)
{
$feedback = $e->getMessage();
}
}
?>
http://php.net/manual/en/function.fputcsv.php
You can pass it a file handle and your data for each row, and it formats it as a CSV line, with correct escapings. It uses a file, though you can use an in memory file stream to avoid hitting the disk
$filename = "php://memory";
$fp = fopen($filename, "w+b");
$rowNum = 1;
while( $row = mysqli_fetch_row( $export ) ) {
if ($rowNum == 1){
fputcsv($fp, array_keys($row)); // Headers
}
fputcsv($fp, $row) // Data
$rowNum++;
}
rewind($fp);
var_dump(stream_get_contents($fp));
You would use the array keys of a row for first CSV row, and array values of each row for data.
Use ';' as delimiter (fputcsv has a parameter for that and it's ',' by default) and set the end of lines in DOS format. At least it's what phpMyAdmin does when doing an export in the "CSV for MS Excel" format.
I am using wordpress and need to dynamically populate a dropdpown. How ever I am having issues with fopen php function in wordpress. https://stackoverflow.com/questions/21990467/
So I've given up trying to import csv file and resorted to just placing my csv file contents into an wordpress options field for a quick fix.
But I am struggling with exploding the csv string safely to then use specific columns for choice label and values.
Can any please advise on how I can do this?
Thank you in advance.
The function
// rider nationality
function motocom_rider_nationality( $field )
{
// reset choices
$field['choices'] = array();
// get the textarea value from options page without any formatting
$choices = get_field('nationality_codes', 'option', false);
// explode the value so that each line is a new array piece
$choices = explode(",", $choices);
// remove any unwanted white space
$choices = array_map('trim', $choices);
$field['choices'] = array(
null => 'Select nationality...'
);
// loop through array and add to field 'choices'
if( is_array($choices) )
{
foreach( $choices as $choice )
{
$label = $choice['Country'];
$value = $choice['A4'];
$field['choices'][ $value ] = $label;
}
}
// Important: return the field
return $field;
}
add_filter('acf/load_field/name=rider_nationality', 'motocom_rider_nationality');
The csv string in the options textarea field...
Country,A2,A3,Number
Aaland Islands,AX,ALA,248
Afghanistan,AF,AFG,4
Albania,AL,ALB,8
Algeria,DZ,DZA,12
Samoa,AS,ASM,16
Andorra,AD,AND,20
Fixed it using this solution...
// csv to array
function motocom_csv_to_array($filename='', $delimiter=',')
{
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
{
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
// rider nationality
function motocom_rider_nationality( $field )
{
// reset choices
$field['choices'] = array();
// get the textarea value from options page without any formatting
$choices = motocom_csv_to_array( get_template_directory() . '/csv/nationality-codes.csv' );
$field['choices'] = array(
null => 'Select nationality...'
);
// loop through array and add to field 'choices'
if( is_array($choices) )
{
foreach( $choices as $choice )
{
$label = $choice['Country'];
$value = $choice['A3'];
$field['choices'][ $value ] = $label . ' [' . $value . ']';
}
}
// Important: return the field
return $field;
}
add_filter('acf/load_field/name=rider_nationality', 'motocom_rider_nationality');