Hopefully someone can assist, I currently coding pages for a game manual and i'm using two functions I found here, one to pull text/formatting from a html file and the other to pull data from a CSV file and insert it into a table. If I have more than one section to include in the page I have been duplicating the code. An example of the result can be found here
As you can see the page shows three sections and this is the result I want. What i'm wondering is if there is a more efficient way than how I am currently doing it which is by copying the code and just altering the variables for every file I want to import? As you can see the variable name is set by the page name. Below is the code I am using.
//function to display csv as table
function csvimport($filename, $header = false)
{
$handle = fopen($filename, "r");
echo '<table id="subman">';
//display header row if true
if ($header) {
$csvcontents = fgetcsv($handle);
echo '<tr>';
foreach ($csvcontents as $headercolumn) {
echo "<th>$headercolumn</th>";
}
echo '</tr>';
}
// displaying contents
while ($csvcontents = fgetcsv($handle)) {
echo '<tr>';
foreach ($csvcontents as $column) {
echo "<td>$column</td>";
}
echo '</tr>';
}
echo '</table>';
fclose($handle);
}
I then use the following to select the CSV file to use and display as a table.
csvimport("$data", "true");
defined by the variable $data
//get page name from link or use manual as default
$page = $_GET['page'] ?? 'manual';
//combine page name with suffix and set page variables
$data = "{$page}.csv";
I use similar for the html as shown below.
$myfile = fopen("$text", "r") or die("Unable to open file!");
echo fread($myfile, filesize("$text"));
fclose($myfile);
So I can get multiple files to display in order I copy the code and add these variables.
$data = "{$page}.csv";
$data2 = "{$page}2.csv";
$data3 = "{$page}3.csv";
Hopefully I have explained myself and what I am trying to ask.
Thank you all in advance for reading :)
You should learn how modern web frameworks work. They separate the view, the model and the controller. The model is the logical architecture of your application, the controller is the code to route and render each page, and the view is all the html output and the styling.
Viewing your code I would separate first the view. Here I have done a first step of what I'm saying. It is only a first step, I recommend you to learn a few (a lot of) programming concepts, to use composer components, to look deeply at one of the million php (micro)frameworks or to roll your own. There is a lot of oportunities nowadays to do php the right way.
Separation of the controller and the templates
index.php
function csvimport($filename, $delimiter = ',') {
$handle = fopen($filename, "r");
$output = [];
while ($csvcontents = fgetcsv($handle, 1024, $delimiter)) {
$output[] = $csvcontents;
}
fclose($handle);
return $output;
}
function tpl($fileName, $data = false) {
$rendered = "";
if (file_exists($fileName)) {
ob_start();
extract($data);
require($fileName);
$rendered = ob_get_contents();
ob_end_clean();
}
return $rendered;
}
$data['header'] = true;
$data['csvcontents'] = csvimport(CSV_FILE, ';');
echo tpl('table.tpl.php', $data);
table.tpl.php
<table id="subman">
<?php
$first = true;
foreach ($csvcontents as $row) :
if ($first) :
$first = false;
if ($header) :
$tag = 'th';
else:
continue;
endif;
else:
$tag = 'td';
endif;
?>
<tr>
<?php foreach ($row as $column) : ?>
<<?= $tag ?>><?= $column ?></<?= $tag ?>>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
The index has a few functions to read csv and render any template and the template holds all the html output. This is only a first approach, far for being a production ready code, use at your own risk and never trust user input
Related
I am trying to display a CSV file in a paginated format using PHP. I am using HTML to display the header information from CSV. I am using HTML because if I go to the remaining pages, the header remains in the table. However, in the first page alone I get the header information twice. I tried to remove it using str_replace and preg_replace but to no luck. This is the code I have so far.
<?php
$names = file('demo.csv');
$page = $_GET['page'];
//constructor takes three parameters
//1. array to be paged
//2. number of results per page (optional parameter. Default is 10)
//3. the current page (optional parameter. Default is 1)
$pagedResults = new Paginated($names, 50, $page);
$handle = fopen('demo.csv', 'r');
if (($data = fgetcsv($handle, 1000, ',')) !== FALSE)
{
}
echo "<table id='kwTable' border='4' bgcolor='#adb214' style='float:center; margin:100'>";
echo '<tr><th>'.implode('</th><th>', $data).'</th></tr>';
?>
<tbody id="kwBody">
<?php
//when $row is false loop terminates
while ( $row = $pagedResults->fetchPagedRow())
{
echo "<tr><td>";
//echo '<tr><th>'.implode('</th><th>', $data).'</th></tr>';
//Here I am getting the header information from the CSV file twice.
$row1 = str_replace( ',', "</td><td>", $row );
echo $row1;
echo "</td></tr>";
}
fclose($handle);
echo "</table>";
//important to set the strategy to be used before a call to fetchPagedNavigation
$pagedResults->setLayout(new DoubleBarLayout());
echo $pagedResults->fetchPagedNavigation();
If you have just one header row at the top of the CSV then you just need to skip the row on first pass:
$header = true;
if (!$page) $page = 1;
while ( $row = $pagedResults->fetchPagedRow())
{
if ($page == 1 && $header) {
$header = false;
continue; // Skip this header row
}
echo "<tr><td>";
//echo '<tr><th>'.implode('</th><th>', $data).'</th></tr>';
//Here I am getting the header information from the CSV file twice.
$row1 = str_replace( ',', "</td><td>", $row );
echo $row1;
echo "</td></tr>";
}
I have to create a dynamic site map for a uni assignment using PHP.
I have saved the names of the links in a text file called "sitemap.txt". These names are the names of the pages minus their extensions and I am supposed to use this content to generate a link. The content looks like this:
Index,Services,Contact Us,Register,Login,Class Manager
My code is below:
<?php
$fp = fopen("sitemap.txt", "r");
echo '<p class="smallerText">';
while(!feof($fp))
{
$line = fgets($fp);
$array = explode(",", $line);
}
fclose($fp);
$num_elements = count($array);
$list = '<ul class="servicesList" name="sitemap">';
for($count = 0; $count < $num_elements; $count++)
{
$list .= "<li>$array[$count]</li>";
}
$list .= "</ul>";
echo "$list";
?>
So basically I have been able to print the contents of the file to the page without any issues. But I need to convert the static text into links.
Can anyone suggest a way? I was thinking using regex or string matching but I'm not sure how.
I am not sure what you are asking, but if it's creating link out of those names, can't you just ....
$YourDomain="http://mydomain.com/";
$ext=".php";
for($count = 0; $count < $num_elements; $count++)
{
$list .= "<li>$array[$count]</li>";
}
Could someone help me with this?
I have a folder with some files (without extention)
/module/mail/templates
With these files:
test
test2
I want to first loop and read the file names (test and test2) and print them to my html form as dropdown items. This works (the rest of the form html tags are above and under the code below, and omitted here).
But I also want to read each files content and assign the content to a var $content and place it in an array I can use later.
This is how I try to achieve this, without luck:
foreach (glob("module/mail/templates/*") as $templateName)
{
$i++;
$content = file_get_contents($templateName, r); // This is not working
echo "<p>" . $content . "</p>"; // this is not working
$tpl = str_replace('module/mail/templates/', '', $templatName);
$tplarray = array($tpl => $content); // not working
echo "<option id=\"".$i."\">". $tpl . "</option>";
print_r($tplarray);//not working
}
This code worked for me:
<?php
$tplarray = array();
$i = 0;
echo '<select>';
foreach(glob('module/mail/templates/*') as $templateName) {
$content = file_get_contents($templateName);
if ($content !== false) {
$tpl = str_replace('module/mail/templates/', '', $templateName);
$tplarray[$tpl] = $content;
echo "<option id=\"$i\">$tpl</option>" . PHP_EOL;
} else {
trigger_error("Cannot read $templateName");
}
$i++;
}
echo '</select>';
print_r($tplarray);
?>
Initialize the array outside of the loop. Then assign it values inside the loop. Don't try to print the array until you are outside of the loop.
The r in the call to file_get_contents is wrong. Take it out. The second argument to file_get_contents is optional and should be a boolean if it is used.
Check that file_get_contents() doesn't return FALSE which is what it returns if there is an error trying to read the file.
You have a typo where you are referring to $templatName rather than $templateName.
$tplarray = array();
foreach (glob("module/mail/templates/*") as $templateName) {
$i++;
$content = file_get_contents($templateName);
if ($content !== FALSE) {
echo "<p>" . $content . "</p>";
} else {
trigger_error("file_get_contents() failed for file $templateName");
}
$tpl = str_replace('module/mail/templates/', '', $templateName);
$tplarray[$tpl] = $content;
echo "<option id=\"".$i."\">". $tpl . "</option>";
}
print_r($tplarray);
Basically the code below reads in a text file and diplays it on the screen with checkboxes near each line. But now I want the user to be able to check any box and then display the selected results in a new PHP file - I thought I would have to read in the text file again and somehow refer it to the array, but I'm still stuck, so any help would be appreciated.
Thank you.
First php file
<?php
$filename = "file.txt";
$myarray = file($filename);
print "<form action='file2.php' method='post'>\n";
// get number of elements in array with count
$count = 0; // Foreach with counter is probably best here
foreach ($myarray as $line) {
$count++; // increment the counter
$par = getvalue($line);
if ($par[1] <= 200) {
// Note the [] after the input name
print "<input type='checkbox' name='test[$count]' /> ";
print $par[0]." ";
print $par[1]." ";
print $par[2]." ";
print $par[3]."<br />\n";
}
}
print "</form>";
Second php file which should display the selected results
<?php
$filename = "file.txt";
$myarray = file($filename);
?>
I think you're over complicating the problem. You can just give the checkboxes a value atribute and read the array from the second page. Start with kus print_r ($_POST) on the second page to help you see what you have to work with.
1) Think of format of your text file (could be something like "Name1-Value 1-true\nName1-Value2-false")
2) Learn this function
3) Create a file with the default options
4) Make a PHP script that opens the file, makes an array and prints the resoult - for example:
$handle = fopen('./file.txt','r');
$fileString = fread($handle,filesize('./file.txt'));
$handle = null; //Similar to unset($handle);
$array = explode($fileString, "\n");
echo '<form action="./script2.php">';
foreach ($array as $value) {
$value = explode($value, "-");
echo '<input type="checkbox" name="'.$value[1].'" value="'.$value[2].'" checked="';
if ($value[3]==true) {
echo 'checked" /><br />';
} else {
echo '" /><br />';
}
}
5) Make the second script that edits the file - for example:
if ($_GET == null;) {exit("He's dead, Jim!");}
$handle = fopen('./file.txt','r');
$fileString = fread($handle,filesize('./file.txt'));
//Do something with the string :D
$handle = fopen('./file.txt','w');
fwrite($handle,$fileString);
I am using WP Alchemy to create a meta box with multiple check boxes.
The trouble I'm having is, I have a csv list of academic courses that I want to create the check box options from. So I'm taking the csv turning it into an array that the boxes are made from. However with the code I have now, only the LAST line is created in the array.
<?php
$file_handle = fopen('curriculum.csv', 'r');
while (!feof($file_handle) ) {
$line_of_text = fgets($file_handle);
$parts = explode(',', $line_of_text);
$items = array ($parts[2] .$parts[3], );
}
fclose($file_handle);
?>
<?php foreach ($items as $i => $item): ?>
<?php $mb->the_field('cb_ex3'); ?>
<!-- similar to test #2, the same thing can be accomplished by simply
adding array brackets "[]" to the name -->
<input type="checkbox" name="<?php $mb->the_name(); ?>[]" value="<?php echo $item; ?>"<?php $mb->the_checkbox_state($item); ?>/> <?php echo $item; ?><br/>
<?php endforeach; ?>
So out of the few hundred lines of code, all I get is the last line.
Here is the actually file I'm working with: http://www.ouhsd.k12.ca.us/educational_services/curriculum/curriculum.csv
In each iteration of the loop you replace $items when you want to add to it, thus it only having the last value.
Also http://php.net/fgetcsv might be of some use to you.
You should be using the fgetcsv() (docs) function rather than trying to make sense of the CSV data yourself. Also, you should build the $items array (rather than overwriting it) as you loop over the file, adding a new item each time.
$file_handle = fopen('curriculum.csv', 'r');
fgets($file_handle); // this skips the csv header line
while (($parts = fgetcsv($file_handle)) !== FALSE) {
$items[] = $parts[2] . ' ' . $parts[3];
}
fclose($file_handle);
foreach ($items as $item) {
// Your HTML code goes here
echo $item . PHP_EOL;
}
Bonus points (you'll look cooler, using objects and iterators!)
$file = new SplFileObject('curriculum.csv');
$file->setFlags(SplFileObject::READ_CSV);
foreach (new LimitIterator($file, 1) as $parts) {
$items[] = $parts[2] . ' ' . $parts[3];
}
foreach ($items as $item) {
// Your HTML code goes here
echo $item . PHP_EOL;
}
items should be an array in your case. Initialize it outside the while loop
$items = array();
And then inside the while loop
$items[] = array ($parts[2] .$parts[3], );
should work.
Also look at fgetcsv as well as suggested.
You need an extra dimenson to your array.
$i=0;
$items= new array(); // i think you need this for some fun reason
while (!feof($file_handle) ) {
$line_of_text = fgets($file_handle);
$parts = explode(',', $line_of_text);
$items[$i] = array ($parts[2] .$parts[3], );
}
You are overwriting the $items array. I would like to suggest a much simpler method to
<code><pre><?php
// in one step, load the datafile as an array, and loop over each line
// then explode the line by comma, and add to $lines array
foreach(file('curriculum.csv') as $line)
$lines[] = explode(',',$line);
// display the structure of the captured data
print_r($lines);
?></pre></code>
I think once you understand the structure of the captured data here, you can use the values as you wish in your output loop.
code, pre and php tags added for convenience