PHP inserting parsed values from text file into MySQL DB - php

I'm new to PHP and am trying to parse certain text from a txt file, and then insert the text into a MySQL database. So, let's get more specific. The file's format is as such, and it is repeated through the document end. the ellipses represent the previous and next tones.
...
[Tone27]
Atone = 707.3
Btone = 746.8
Btonelength = 3
Btonedebounce = 1
Description = Fire Department 1
mp3_Emails = email#address.com,email2#address.com,email3#address.com
amr_Emails = email2#textmessaging.com,email1#textmessaging.com
alert_command = c:\test.bat
post_email_command = c:\test2.bat
radio_frequency = 154.475
exclude_from = 13:25
exclude_to = 13:35
exclude_emails = email2#textmessaging.com,email2#address.com
...
What I want to do is parse the first items(e.g. '[tone27]') in each "tone block" from the file and insert it into the first field of a NEW row in the db. I then need to evaluate what comes before each line's " = ", for instance "Atone," and insert what comes after that line's " = ", for instance "707.3" into a field by that name. so, this row may look like this in the db:
$id | [tone27] | 707.3 |746.8 | 3 | 1 | Fire Department 1 |email1#x.com,email2#x.com,e...|...
and so on...
i've been able to isolate each thing by performing string functions, but am unsure of how to set up a loop that would insert each value properly. Here's the code I used to isolate them, but it's not helping at all with actually getting them into the database.
$txt_file = file_get_contents('config/tones.txt');
$rows = explode("\n", $txt_file);
foreach($rows as $row => $data)
{
$row_data = explode(' = ', $data);
if ((isset($row_data[0])) && ($row_data[0] !== " " )){
$info[$row]['attribute'] = $row_data[0];
$info_attribute = trim($info[$row]['attribute']);
}
if (isset($row_data[1])){
$info[$row]['value'] = $row_data[1];
$info_value = trim($info[$row]['value']);
//display data
echo 'Row ' . $row . ' Attribute: ' . $info_attribute . '<br />';
echo 'Row ' . $row . ' Value: ' . $info_value . '<br />';
} elseif (($info[$row]['attribute']) && (!empty($info_attribute))) {
echo "<br>";
echo 'Row ' . $row . ' Attribute: ' . $info_attribute . '<br />';
continue;
}
I'M A NOOB, NO DOUBT. I'M LOST. Thanks in advance for your help!!!
****|| EDIT ||****
Thanks for all of the excellent answers! here's what I've resultingly come up with. No queries yet, just a simple dash of the read portion of CRUD, but the code will be the same, only with queries. A big thanks to #leepowers for introducing me to the wonderful parse_ini_file() function.
foreach(parse_ini_file("config/tones.txt", true) as $k => $v){
extract($v, EXTR_SKIP);
echo "<br>";
echo $k . "<br>";
foreach($v as $sv => $ssv){
$lcase_sv = strtolower($sv);
if (trim($lcase_sv) == 'amr_emails'){
echo "sv: amr_Emails:<br>";
echo "ssv:<br>";
$eA = explode(',', trim($ssv));
foreach($eA as $eK => $eV){
echo "email" . filter_var($eK + 1, FILTER_SANITIZE_NUMBER_INT) . ": " . $eV . "<br>";
}
} elseif (trim($lcase_sv) == 'mp3_emails'){
echo "ssv:<br>";
$eA = explode(',', trim($ssv));
foreach($eA as $eK => $eV){
echo "email" . filter_var($eK + 1, FILTER_SANITIZE_NUMBER_INT) . ": " . $eV . "<br>";
}
}else {
echo "sv: " . $sv .", " . "s: " . $ssv . "<br>";
}
}
}

Use parse_ini_file to load the data structure into an array.
From there you can build and execute SQL statements:
$entries = parse_ini_file("config/tones.txt", true);
foreach ($entries as $section => $fields) {
extract($fields, EXTR_SKIP);
$sql = "INSERT INTO mytable (section, atone, btone) VALUES ($section, '$Atone', '$Btone'";
....
}
Of course, you'll need to prepare and escape the SQL statement before executing it.

parse_ini_file($source); return an associative array
$query = 'INSET INTO ... (key, value) VALUES (:key, :value)';
$stmt = DB::prepare($query);
foreach( parse_ini_file($source) as $key => $value )
{
$stmt->execute(array(':key' => $key, ':source' => $source));
}
This example use PDO
Just output of file in loop is:
foreach( parse_ini_file($source) as $key => $value )
{
echo $key; // Atone in first loop
echo $value; //707.3 in first loop
// BUT NOT USE THIS!!! use mysqli or PDO
mysql_query("INSERT INTO ... (key, value) VALUES ($key, $value)");
}

Here's another way to do it. Just need to modify it according to you needs (number of rows/credentials). It's better to use PDO.
$username = 'yourusername';
$password = 'yourpass';
try {
$conn = new PDO('mysql:host=127.0.0.1;dbname=yourdbname', $username, $pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo 'successfully connected';
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
foreach(parse_ini_file('yourfile.ini', true) as $row)
{
try {
// just adjust the number of columns accordingly
$stmt = $conn->prepare('insert into tablename values(?,?,?,?,?,?,?,?,?,?,?,?,?)');
// $row contains the values to insert
$stmt->execute($row);
echo 'rows affected' . $stmt->rowCount(); // 1
}catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}

Related

Query produces data, but the export is blank

I was recently tasked to update some older sites from MySQL to MySQLi.
Though slow and steady, the update has been ok until I ran into an issue when exporting some data to an excel document.
This code was written by a previous developer. There's a lot going on in the file, and I hope I'm grabbing the part that is supposed to be creating the excel document:
<?php
$export = mysqli_query ( $session->connDB(),$sql ) or die ( "Sql error : " . mysqli_error( ) );
$fields = mysqli_num_fields ( $export );
$num_rows = mysqli_num_rows( $export );
$pattern = '/[A-Z0-9][A-Z0-9._-]+#[A-Z0-9][A-Z0-9.-]{0,61}[A-Z0-9]\.[A-Z.]{2,6}/i'; //email
$phonpat = '/(\(?([0-9]{3})+\)?[\-\s\.]?([0-9]{3})+[\-\s\.]?([0-9]{4})(( |-|\.)?[ext\.]+ ?\d+)|\(?([0-9]{3})+\)?[\-\s\.]?([0-9]{3})+[\-\s\.]?([0-9]{4}))/i'; //telephone
$phPat = '/([0-9]{3})([0-9]{3})([0-9]{4})/';
$vippatt = '/VIP/i';
for($f=0; $f<$fields; $f++){
$header.='"'.mysqli_fetch_fields($export, $f).'"'."\t";
}
for($i=0; $i<$num_rows; $i++){
for($x=0; $x<$fields; $x++){
$email = mysqli_fetch_assoc($export,$i,"EMAIL");
$phone = mysqli_fetch_assoc($export,$i,"PHONE");
$viprm = mysqli_fetch_assoc($export,$i,"VIP");
preg_match ($pattern, $email, $matches);
preg_match ($phonpat, $phone, $phoneno);
preg_match ($vippatt, $viprm, $vpmatch);
if(isset($matches[0])) {$emal=strtolower($matches[0]);} else {$emal="";}
if(isset($vpmatch[0])) {$vips=strtoupper($vpmatch[0]);} else {$vips="";}
if(isset($phoneno[0])) {$phne=preg_replace($phPat,'($1) $2-$3 ',formatPhone($phoneno[0],false,false));} else {$phne="";}
if(mysqli_fetch_fields($export, $x)=='EMAIL'){
$fld=$emal;
} else {
if(mysqli_fetch_fields($export, $x)=='PHONE'){
$fld=$phne;
} else {
if(mysqli_fetch_fields($export, $x)=='VIP'){
$fld=$vips;
} else {
if(mysqli_fetch_fields($export, $x)=='UNITS'){
$fld=1;
} else {
$fld = mysqli_fetch_assoc($export,$i,mysqli_fetch_fields($export, $x));
}
}
}
}
$data.= '"'.$fld.'"'."\t";
}
$data.="\n";
}
?>
Here is where the code checks if the data is blank or not, and then exports the spreadsheet:
<?php
if ($data == "") {
$data = "\nNo records found for your search parameters.\n\n".$sql;
} else {
echo "should show data";
}
global $time;
$time = time();
header("Content-Disposition: attachment; filename=CargoManagementCustomReport-$time.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";
?>
When the spreadsheet gets exported, I see "should show data". This tells me the $data variable obviously has data. It's just not getting into the spreadsheet.
If you'll notice in the above, I'm using mysqli_fetch_fields. This was used to replace mysql_field_name (in my attempt to update to MySQLi).
I also tried mysqli_fetch_field, but got the same results.
I am getting no errors, but the spreadsheet is still blank.
I can echo $sql to get the query, and I can run the query in the database and it returns data.
What am I doing wrong and how can I fix it?
That whole code is gibberish, so I hope I understood what it is that it was meant to do.
Here are the main problems:
mysqli_fetch_fields() takes only 1 argument and returns an array of objects. You can't cast an array to a string. I assume you wanted to get the field name.
mysqli_fetch_assoc() takes only 1 argument and returns an array of data in an associative array as the name suggests. It also moves the internal pointer to the next row every time it is called. You are trying to use it as if it was mysql_result().
Your nested loops are very messy. I replaced them with simple foreach loops and replaced the nested if statements with a switch. While I would normally stay away from such constructs, this is the easiest way to migrate this code.
After removing all the mysqli nonsense, the code is now readable. It iterates over every field of every row, applying some transformations to some fields and concatenating the result into a string.
Fixed code:
$conn = $session->connDB();
$export = mysqli_query($conn, $sql);
$pattern = '/[A-Z0-9][A-Z0-9._-]+#[A-Z0-9][A-Z0-9.-]{0,61}[A-Z0-9]\.[A-Z.]{2,6}/i'; //email
$phonpat = '/(\(?([0-9]{3})+\)?[\-\s\.]?([0-9]{3})+[\-\s\.]?([0-9]{4})(( |-|\.)?[ext\.]+ ?\d+)|\(?([0-9]{3})+\)?[\-\s\.]?([0-9]{3})+[\-\s\.]?([0-9]{4}))/i'; //telephone
$phPat = '/([0-9]{3})([0-9]{3})([0-9]{4})/';
$vippatt = '/VIP/i';
foreach (mysqli_fetch_fields($result) as $field) {
$header .= '"' . $field->name . '"' . "\t";
}
$data = '';
foreach ($export as $row) {
foreach ($rows as $fieldName => $value) {
switch ($fieldName) {
case 'EMAIL':
preg_match($pattern, $value, $matches);
$data .= '"' . (isset($matches[0]) ? strtolower($matches[0]) : '') . '"' . "\t";
break;
case 'PHONE':
preg_match($phonpat, $value, $phoneno);
$phne = "";
if (isset($phoneno[0])) {
$phne = preg_replace($phPat, '($1) $2-$3 ', formatPhone($phoneno[0], false, false));
}
$data .= '"' . $phne . '"' . "\t";
break;
case 'VIP':
preg_match($vippatt, $value, $vpmatch);
$data .= '"' . (isset($vpmatch[0]) ? strtolower($vpmatch[0]) : '') . '"' . "\t";
break;
case 'UNITS':
$data .= '"1"' . "\t";
break;
default:
$data .= '"' . $value . '"' . "\t";
break;
}
}
$data .= "\n";
}

Loop through associative array and assign values

I have an array:
$instructions = array (
array("step_no"=>"1","description"=>"Ensure that you have sufficient balance"),
array("step_no"=>"2","description"=>"Approve the request sent to your phone")
);
What I want is to loop through this array, which I have done, but I am now confused because I don't know how to get the output I desire.
foreach ($array as $key => $value) {
//echo $key . "\n";
foreach ($value as $sub_key => $sub_val) {
if (is_array($sub_val)) {
//echo $sub_key . " : \n";
foreach ($sub_val as $k => $v) {
echo "\t" .$k . " = " . $v . "\n";
}
} else {
echo $sub_key . " = " . $sub_val . "\n";
}
}
}
The above code loops through the array, but this line of code:
echo $sub_key . " = " . $sub_val . "\n";
gives me:
step_no = 1 description = Ensure that you have sufficient balance step_no = 2 description = Approve the request sent to your phone
when I change it to:
echo $sub_val . "\n";
it gives me:
1 Ensure that you have sufficient balance 2 Approve the request sent to your phone
But I what I truly want is:
1. Ensure that you have sufficient balance
2. Approve the request sent to your phone
Is this possible at all? Thanks.
$instructions = array (
array("step_no"=>"1","description"=>"Ensure that you have sufficient balance"),
array("step_no"=>"2","description"=>"Approve the request sent to your phone")
);
foreach($instructions as $instruction) {
echo $instruction['step_no'] . '. ' . $instruction['description'] . "\n";
}
If it's HTML you may want to use <ol> and <li>.
It smells like you are not running this script in command line but in browser. If so, then \n makes no visual effect (unless within <pre> block) and you u must use HTML tag <br /> instead. Also, drop concatenation madness and use variable substitution:
echo "{$sub_key}. = {$sub_val}<br/>";
You can simple achieve this way
<?php
$instructions = array (
array("step_no"=>"1","description"=>"Ensure that you have sufficient balance"),
array("step_no"=>"2","description"=>"Approve the request sent to your phone")
);
foreach($instructions as $instruction){
echo $instruction['step_no'].'. '.$instruction['description'].PHP_EOL;
}
?>
Alway keep it simple.

Parsing json with a nested element

does not work with a nested element
the elements of the first level are output, and the nested array with data is not read, as it is possible to get values - id, title and location?
<?php
function removeBomUtf8($s){
if(substr($s,0,3)==chr(hexdec('EF')).chr(hexdec('BB')).chr(hexdec('BF'))){
return substr($s,3);
}else{
return $s;
}
}
$url = "https://denden000qwerty.000webhostapp.com/opportunities.json";
$content = file_get_contents($url);
$clean_content = removeBomUtf8($content);
$decoded = json_decode($clean_content);
while ($el_name = current($decoded)) {
// echo 'total = ' . $el_name->total_items . 'current = ' . $el_name->current_page . 'total = ' . $el_name->total_pages . '<br>' ;
echo ' id = ' . $el_name->data[0]->id . ' title = ' . $el_name->data.title . ' location = ' . $el_name->data.location . '<br>' ;
next($decoded);
}
?>
$el_name->data[0]->id is correct
$el_name->data.title is not
you see the difference?
and $decoded is the root (no need to iterate over it) - you want to iterate over the data children
<?php
foreach($decoded->data as $data)
{
$id = (string)$data->id;
$title = (string)$data->title;
$location = (string)$data->location;
echo sprintf('id = %s, title = %s, location = %s<br />', $id, $title, $location);
}

unable to generate multiple random words at a time using order by rand using php mysql

Hi friends am trying to produce random words using order by rand but unable to produce.Here is my code
for($i=0;$i< 10;$i++) {
$result = mysqli_query($conn,"SELECT * FROM questions ORDER BY RAND() LIMIT 2");
if (!$result) {
/*die('Invalid query: ' . mysql_error());*/
die("Query failed".mysqli_error());
}
while ($row = mysqli_fetch_array($result)) {
$meta_descriptions = '{' $row['fact'] . ' ' . '|' $row['fact'] . '|' . $row['fact']}';
echo $meta_descriptions;
}
}
My questions table has one column that is column fact. i t has three values like
apple
ball
cat
Am getting output as
ball |ball| ball only
I want it to be random like
ball|cat|apple
How can I generate it
See this statement inside your while() loop,
$meta_descriptions = '{' $row['fact'] . ' ' . $row['fact'] . '}';
You're using same column value two times in each iteration of while() loop. Simply change your while() code section in the following way,
$meta_descriptions = '';
while ($row = mysqli_fetch_array($result)) {
$meta_descriptions .= $row['fact'] . '|';
}
$meta_descriptions = rtrim($meta_descriptions, '|');
echo $meta_descriptions;
Alternative method:
Create an empty array in the beginning. In each iteration of while() loop, push $row['fact'] value to this array. And finally apply implode() function on this array to get the desired result.
So your code should be like this:
$meta_descriptions = array();
while ($row = mysqli_fetch_array($result)) {
$meta_descriptions[] = $row['fact'];
}
$meta_descriptions = implode('|', $meta_descriptions);
echo $meta_descriptions;
change inside your while loop.
$meta_descriptions = '{';
$descriptions = array();
while ($row = mysqli_fetch_array($result)) {
$descriptions[] = $row['fact'];
}
$meta_descriptions .= implode(" | ",descriptions);
$meta_descriptions .= '}';
echo $meta_descriptions;

mssql_fetch_array only displays one row if columns are put into variables

I'm still a PHP noob, so I apologize if this is something simple.
I am creating a fairly basic search facility for a website using PHP and mySQL. I have connected to the database, selected the database, queried the table and have fetched the table columns;
$k = htmlspecialchars($_GET['k']); // Get search query
$select = mssql_query("SELECT * FROM search WHERE Title Like '%" . $k . "%'");
if( mssql_num_rows($select) < 1) {
$noResults = 'No results found for <b>' . $k . '</b>, <label for="k">Please try again.</label>';
} else {
while ($results = mssql_fetch_array($select)) {
$title = $results['Title'];
$link = $results['Link'];
$description = $results['Description'];
}
}
When I put the $results[''] columns into variables and then try to echo out each variable like so;
if( isset($noResults)) {
echo $noResults;
} else {
echo '<li>' . '<h2>' . '' . $title . '' . '</h2>' . '<p>' . $link . '</p>' . '<p>' . $description . '</p>' . '</li>';
}
it only echo's out one row matching that query however, If I was to just simple echo out the columns like so;
echo $results['Title'];
echo $results['Link'];
echo $results['Description'];
all rows matching the query will be displayed..
I'm not sure why this is happening. If someone could help me out that would be great!
You need to use a loop:
$k = mysql_real_escape_string($_GET['k']); // Get search query
$select = mssql_query("SELECT * FROM search WHERE Title Like '%" . $k . "%'");
if( mssql_num_rows($select) < 1) {
$noResults = 'No results found for <b>' . $k . '</b>, <label for="k">Please try again.</label>';
} else {
$results= array();
while ($result = mssql_fetch_array($select)) {
$results[]= $result;
}
}
if( isset($noResults)) {
echo $noResults;
} else {
echo "<ul>";
foreach($results as $result){
echo '<li>' . '<h2>' . '' . $result['title'] . '' . '</h2>' . '<p>' . $result['link'] . '</p>' . '<p>' . $result['description'] . '</p>' . '</li>';
}
echo "</ul>";
}
Do you execute the output in the while-loop?
If you execute the while-loop and call the echo after that, each resultset will overwrite the previous, and the echo will output the last resultset which was fetched.
If you call the echo in the Loop, every result set will generate "his own" output line.
If you want to hold every resultset in a variable you can use an array, which is declared in front of the loop and gets filled in the loop.
a few things are not clear from your question, but i am assuming that you are echo'ing the variables outside the loop since you are checking isset($noResults). that means you are reassigning the variables with new values in each loop of while. so ultimately you get the last one assigned to the variables. you have to either use an array to hold the values or echo it with in the loop.

Categories