Linux System
Looking for help with my function. I'm new learning them. It was mentioned to create a function to keep from writing the same code too many times.
I have found many pages about them and they have helped but I'm still having issues getting mine to work.
It is not giving any log errors and nothing is being created. I always get errors when starting with something so I know I'm missing something.
Here is what I have so far.
Thank you in advance.
Bob
<?php
$dirPath = "Path to File Location";
$buildPath = "Path to File Location";
function createFiles() {
for ($i = 1; $i < 45; ++$i) {
$filename = $buildPath . '/$area'. sprintf("%02s", $i) . '.php';
if (!file_exists($buildPath$filename)) {
$myfile = fopen($buildPath$filename, "w") or die("Unable to open item$i file!");
fwrite($myfile, $txt1);
fwrite($myfile, $addtitle);
fwrite($myfile, $incltxt);
fclose($myfile);
chmod("$buildPath"."$area"."$i".".php", 0755);
}
// fopen, fwrite, fcloses...
// filename for delete page setup
if (!file_exists("$dirPath"."delete.page.php")) {
$myfile = fopen("$dirPath"."delete.page.php", "w") or die("Unable to open file!");
$txt = "<option value=\"\">Select Page to Delete......</option>\n
<option value=\"generalinfo.tx\">General Information Page.</option>\n
<option value=\"$filename\">$area Pg. $i</option>\n";
fwrite($myfile, $txt);
fclose($myfile);
chmod("$dirPath"."delete.page.php", 0755);
}
else
{
$myfile = fopen("$dirPath"."delete.page.php", "a") or die("Unable to open file!");
$txt = "<option value=\"$filename\">$area Pg. $i</option>\n";
fwrite($myfile, $txt);
fclose($myfile);
chmod("$dirPath"."delete.page.php", 0755);
}
break;
}
return true;
}
if ($i == 1) {
createFiles();
}
// Once we get more than 4 items written in each file we need a new file.
// This can happen maximum 11 times for each session
if ($i == 5) {
createFiles();
}
if ($i == 9) {
createFiles();
}
if ($i == 13) {
createFiles();
}
if ($i == 17) {
createFiles();
}
etc......
if($i == 49) {
echo "<br />Maximum of 12 pages hit. Time to delete a few";
}
?>
$i is if it equals, and that part is working.
If that part is working, then you are not showing all your code!
Take this example, which is fundamentally the same as what you are doing:
function createFiles()
{
$i = 3;
}
if ($i == 3)
{
createFiles();
echo "is 3";
}
else
{
echo "is not 3";
}
This will ALWAYS echo "is not 3". The var is not set, as the one being set in the function is A) Not within the same global scope, and B) the function has never even been called.
How can a var being manipulated within a function determine in code outside the function if that same function should be called if the var within the function is set to something?
It's catch 22.
Your function call createFiles() will only execute if $i == 1, and the code you posted does not set that var, it will always be null or unset (etc).
That means your if statement which calls the function will never work, and always return FALSE, and so the function will never be called.
You also have to understand global scope, in that vars within the function stay within the function, and any outside the function are separate.
Essentially you currently have two vars, the one inside the function, and the one outside it, although still both named $i their global scope does not marry, so they never interact with one-another.
You can pass a var into the function to allow vars and their data outside the function to be used within the function, and return one out of the function for using the data outside the function.
Also, every time a user uses your code, any vars will be reset, meaning your bunch of ifs to determine if they have used X times will not work as desired.
You cannot do this client side.
You could set a session or cookie, but the client can easily bypass this if they want to (cleaning browser data).
If you truly want to limit them, you will need a persistent data storage method which the client has no access to - either a file, or more solid method would be to increment a database value.
Then if they can use the form again the next day, a cron could run through the table and clear up as required.
EDIT
To get your script working, try introducing a few stages to make it simple.
Stage1: Get the function working on it's own, adding files (or whatever its purpose is for).
Stage2: Manipulate the function being called how you want - i.e. only call function if user has used function < 10 (etc).
You could even break stage1 into a few sub stages, in Stage1a, get function accessing correct directory; Stage1b, get function accessing files; Stage1c, get function writing to files, etc.
Try to avoid writing a script with numerous areas of functionality all in one go, and break it into manageable logical chunks. Doing this, will also help you see separation between different concerns.
Here is my updated code. I tried one more thing before I was going to give up, and here is the one extra line I added and changes I made.
Stupid error. I don't know how you guys can do this all the time. This is the first time I messed with a function in php and spent all day on it. But it's working so I figured I'd share the changes for all.
function createFiles() {
extract($GLOBALS);
for ($n = 1; $n < 45; ++$n) {
$filename = $buildPath . $area . sprintf("%02s", $n) . '.php';
$filenameb = $area . sprintf("%02s", $n) . '.php';
//^ length of number you need, 2 in this case
if (!file_exists($filename)) {
$myfile = fopen($filename, "w") or die("Unable to open item$i file!");
fwrite($myfile, $txt1);
fwrite($myfile, $addtitle);
fwrite($myfile, $incltxt);
fclose($myfile);
chmod("$filename", 0755);
}
break;
}
if (!file_exists("$dirPath"."delete.page.php")) {
$myfile = fopen("$dirPath"."delete.page.php", "w") or die("Unable to open file!");
$txt = "<option value=\"\">Select Page to Delete......</option>\n
<option value=\"generalinfo.php\">General Information Page.</option>\n
<option value=\"$filenameb\">$area Pg. $n</option>\n";
fwrite($myfile, $txt);
fclose($myfile);
chmod("$dirPath"."delete.page.php", 0755);
}
else
{
$myfile = fopen("$dirPath"."delete.page.php", "a") or die("Unable to open file!");
$txt = "<option value=\"$filenameb\">$area Pg. $n</option>\n";
fwrite($myfile, $txt);
fclose($myfile);
chmod("$dirPath"."delete.page.php", 0755);
}
return true;
if ($i == 1) {
createFiles();
}
// Once we get more than 4 items written in each file we need a new file.
// This can happen maximum 11 times for each session
if ($i == 5) {
createFiles();
}
if ($i == 9) {
createFiles();
}
if ($i == 13) {
createFiles();
}
if ($i == 17) {
createFiles();
}
etc......
if($i == 49) {
echo "<br />Maximum of 12 pages hit. Time to delete a few";
Related
I'm creating a code to display the name of a server with enterprise rules, So for don't use Mysql i try a new things (for me) use php to read and rewrite files, that work perfectly for one part of my code and work perfectly but for the second he only read one time, and when i do a f5 the code don't increment.
He rewrite correctly because my file was at 000 and become 001
I try to use file() but he is disable since 7.0, try to use SplFileObject but it don't want to display anything and i don't like it because i understand nothing when i use it so i come back to fopen(),fread() and fwrite() and that don't work. I'm inPHP 7.3.1
The code that works :
<?php
if ( isset($_POST) AND !empty($_POST) ) {
$nom = "./config.txt";
$filez = fopen($nom, "r") or die("Unable to open file!");
$i = fread($filez,filesize($nom));
$year = getdate();
$idy = substr($year[year], 2);
$fichier = fopen("./resultsrv.txt", "w") or die("Unable to write file!");
for ($z; $z<$_POST['nbr']+1 ; $z++) {
$id = sprintf("%04d", $i+$z);
$nome = $_POST['type'].$_POST['OS'].$idy.$id."<br>" ;
echo $nome;
$nomewout = str_replace("<br>", ";", $nome);
fwrite($fichier,$nomewout);
}
$handle = fopen("./config.txt", "w") or die("Unable to write file!");
fwrite($handle,$id);
fclose($fichier);
fclose($handle);
}
?>
and the one that doesn't work because he doesn't increment :
<?php
if ( isset($_POST) AND !empty($_POST) ) {
$fileName = 'confchass.txt';
$read = fopen($fileName,"r");
$fn = fopen($fileName,"w+");
$i = fread($read,filesize($fileName));
$id = sprintf("%03d", $i+1);
echo "<div align='center'><h1>Le Chassis</h1>";
echo $_POST['Marque'].$_POST['DC'].$id;
echo "</div>";
fwrite($fn,$id);
fclose($read);
fclose($fn);
}
?>
I want he output a thing like XXXXXX001 and when i refresh or do a new POST from my forms he output XXXXXX002 and XXXXXX003 .... But he actualy output only XXXXXX001
The problem is that you open the file for reading and then for writing. But from the manual...
'w+' Open for reading and writing; 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.
So this will blank out the file before you read the value from it.
To fix this (using your current method, you should read the value, then open it for writing and write the new value...
$read = fopen($fileName,"r");
$i = fread($read,filesize($fileName));
fclose($read);
$id = sprintf("%03d", $i+1);
echo "<div align='center'><h1>Le Chassis</h1>";
echo $id;
echo "</div>";
$fn = fopen($fileName,"w+");
fwrite($fn,$id);
fclose($fn);
You could shorten this by using file_get_contents() and file_put_contents().
Using PHP 7.3, I'm trying to achieve "tail -f" functionality: open a file, waiting for some other process to write to it, then read those new lines.
Unfortunately, it seems that fgets() caches the EOF condition. Even when there's new data available (filemtime changes), fgets() returns a blank line.
The important part: I cannot simply close, reopen, then seek, because the file size is tens of gigs in size, well above the 32 bit limit. The file must stay open in order to be able to read new data from the correct position.
I've attached some code to demonstrate the problem. If you append data to the input file, filemtime() detects the change, but fgets() reads nothing new.
fread() does seem to work, picking up the new data but I'd rather not have to come up with a roll-your-own "read a line" solution.
Does anyone know how I might be able to poke fgets() into realising that it's not the EOF?
$fn = $argv[1];
$fp = fopen($fn, "r");
fseek($fp, -1000, SEEK_END);
$filemtime = 0;
while (1) {
if (feof($fp)) {
echo "got EOF\n";
sleep(1);
clearstatcache();
$tmp = filemtime($fn);
if ($tmp != $filemtime) {
echo "time $filemtime -> $tmp\n";
$filemtime = $tmp;
}
}
$l = trim(fgets($fp, 8192));
echo "l=$l\n";
}
Update: I tried excluding the call to feof (thinking that may be where the state becomes cached) but the behaviour doesn't change; once fgets reaches the original file pointer position, any further fgets reads will return false, even if more data is subsequently appended.
Update 2: I ended up rolling my own function that will continue returning new data after the first EOF is reached (in fact, it has no concept of EOF, just data available / data not available). Code not heavily tested, so use at your own risk. Hope this helps someone else.
*** NOTE this code was updated 20th June 2021 to fix an off-by-one error. The comment "includes line separator" was incorrect up to this point.
define('FGETS_TAIL_CHUNK_SIZE', 4096);
define('FGETS_TAIL_SANITY', 65536);
define('FGETS_TAIL_LINE_SEPARATOR', 10);
function fgets_tail($fp) {
// Get complete line from open file which may have additional data written to it.
// Returns string (including line separator) or FALSE if there is no line available (buffer does not have complete line, or is empty because of EOF)
global $fgets_tail_buf;
if (!isset($fgets_tail_buf)) $fgets_tail_buf = "";
if (strlen($fgets_tail_buf) < FGETS_TAIL_CHUNK_SIZE) { // buffer not full, attempt to append data to it
$t = fread($fp, FGETS_TAIL_CHUNK_SIZE);
if ($t != false) $fgets_tail_buf .= $t;
}
$ptr = strpos($fgets_tail_buf, chr(FGETS_TAIL_LINE_SEPARATOR));
if ($ptr !== false) {
$rv = substr($fgets_tail_buf, 0, $ptr + 1); // includes line separator
$fgets_tail_buf = substr($fgets_tail_buf, $ptr + 1); // may reduce buffer to empty
return($rv);
} else {
if (strlen($fgets_tail_buf) < FGETS_TAIL_SANITY) { // line separator not found, try to append some more data
$t = fread($fp, FGETS_TAIL_CHUNK_SIZE);
if ($t != false) $fgets_tail_buf .= $t;
}
}
return(false);
}
The author found the solution himself how to create PHP tail viewer for gians log files 4+ Gb in size.
To mark this question as replied, I summary the solution:
define('FGETS_TAIL_CHUNK_SIZE', 4096);
define('FGETS_TAIL_SANITY', 65536);
define('FGETS_TAIL_LINE_SEPARATOR', 10);
function fgets_tail($fp) {
// Get complete line from open file which may have additional data written to it.
// Returns string (including line separator) or FALSE if there is no line available (buffer does not have complete line, or is empty because of EOF)
global $fgets_tail_buf;
if (!isset($fgets_tail_buf)) $fgets_tail_buf = "";
if (strlen($fgets_tail_buf) < FGETS_TAIL_CHUNK_SIZE) { // buffer not full, attempt to append data to it
$t = fread($fp, FGETS_TAIL_CHUNK_SIZE);
if ($t != false) $fgets_tail_buf .= $t;
}
$ptr = strpos($fgets_tail_buf, chr(FGETS_TAIL_LINE_SEPARATOR));
if ($ptr !== false) {
$rv = substr($fgets_tail_buf, 0, $ptr + 1); // includes line separator
$fgets_tail_buf = substr($fgets_tail_buf, $ptr + 1); // may reduce buffer to empty
return($rv);
} else {
if (strlen($fgets_tail_buf) < FGETS_TAIL_SANITY) { // line separator not found, try to append some more data
$t = fread($fp, FGETS_TAIL_CHUNK_SIZE);
if ($t != false) $fgets_tail_buf .= $t;
}
}
return(false);
}
<?php
$seatsArray = array();
$myFile = fopen("seats.txt", "w") or die("Unable to Open File!");
if(filesize("seats.txt") == 0) {
for($x = 0; $x < 10; $x++) {
fwrite($myFile, "0\n");
}
}
$seatsArray = file("seats.txt", FILE_IGNORE_NEW_LINES);
fclose($myFile);
?>
var array = [<?php echo '"'.implode('","', $seatsArray ).'"' ?>];
This PHP code is at the top of my script section in head. The seats.txt file is full of zeroes initially to represent vacant seats on a flight and through other functions, the seats will fill up (represented by 1s). I can get the 1s to write to the file but as soon as I reload the page, the if-statement seems to execute regardless of its condition being false and resets everything back to zero.
The reason is due to this w mode
w- (Write only. Opens and clears the contents of file; or creates a new file if it doesn't exist)
So every time your file gets blank
Use a or a+ if you want to append at the right of file or r+ if you want to right from starting
I am not sure whether I understand you correctly, but I think you only want to write the file if it does not exist:
<?php
$seatsArray = array();
if(!file_exists("seats.txt") || filesize("seats.txt") == 0) {
$myFile = fopen("seats.txt", "w") or die("Unable to Open File!");
for($x = 0; $x < 10; $x++) {
fwrite($myFile, "0\n");
}
fclose($myFile);
}
$seatsArray = file("seats.txt", FILE_IGNORE_NEW_LINES);
?>
var array = [<?php echo '"'.implode('","', $seatsArray ).'"' ?>];
Additionally, I would recommend putting the filename into a constant, which reduces the risk of typos (so PHP will complain, if it encounters an undefined constant in case of a typo).
I'm having a problem trying to figure out a way to check for a file and if it exists check the next and so on.
I'm not familiar enough with loops so looking for help.
I'm putting together a small set of php forms to help me do rental inspections. The form will create a page for each area/item for the inspection with a photo and description of the problem if any. The form for the photo's is already working and not part of this.
I'm matching the paper form they will have me use. This could save me an hour or so on the windoze spreadsheet they would want me to put everything in and then print to PDF.
My laptop/PC is Linux. Would also save me having to get a Win machine or tablet.
I have everything else working. Just the page creation is giving me fits. I understand a loop should be the easiest to save having to write the file_exists search for each page up to 40 pages.
Here is a snip of were I'm at. The location this is sitting is not publicly accessible.
Thanks in advance
Bob
<?php
// This will be accessed for each area/item inspected
$dirpath = "/localhost/rent.inspect/";
// Get POST info from form page
$a1 = $_POST["a1"];
$a2 = $_POST["a2"];
$a3 = $_POST["a3"];
$a4 = $_POST["a4"];
…...
$a40 = &_POST[“a40”];
// File names we write to can be any name
$FileName1 = "$dirPath/page1.php";
$FileName2 = "$dirPath/page2.php";
$FileName3 = "$dirPath/page3.php";
$FileName4 = "$dirPath/page4.php";
…...
$FileName3 = "$dirPath/page39.php";
$FileName4 = "$dirPath/page40.php";
// Check if the first file is already created.
// If not create it and write, if is does exist check for the
// next file. Keep checking until one not created is found.
// Should never get to the 40th file at this time.
// Check if first file has already been created.
if(file_exists("$FileNam1"))
{
if(file_exists("$FileNam2"))
{
if(file_exists("$FileNam3"))
{
// Check for next one.... Should never see 40
// but keep checking to it just in case something is added
}
else
{
$myfile = fopen("$dirPath/$filename3", "w") or die("Unable to open file!");
$txt = "<font size=\"2\">$a1 $a2 $a3</font></b><br /><br />";
fwrite($myfile, $txt);
fclose($myfile);
}
}
else
{
$myfile = fopen("$dirPath/$filename2", "w") or die("Unable to open file!");
$txt = "<font size=\"2\">$a1 $a2 $a3</font></b><br /><br />";
fwrite($myfile, $txt);
fclose($myfile);
}
}
else
{
$myfile = fopen("$dirPath/$filename1", "w") or die("Unable to open file!");
$txt = "<font size=\"2\">$a1 $a2 $a3</font></b><br /><br />";
fwrite($myfile, $txt);
fclose($myfile);
}
?>
Several ways to do so, an easy one fitting your current problem could be :
for ($i = 1; $i < 41; ++$i) {
if (!file_exists($dirPath . '/page' . $i . '.php')) {
// fopen, fwrite, fclose ...
break;
}
}
You could also improve your variable initializations using an array to store your variables, even more when it's all about changing an increment integer.
Here is an example, not really useful, but explaining how you could do :
for ($i = 0; $i < 41; ++$i) {
$myVar['a' . $i] = $_POST['a' . $i];
}
you can check till the file exixts and increment the counter
$filepath = "/somepath/";
$filename = "FileNam"
$i=1;
$pathtocheck = $filepath + $filename + $i;
while ( file_exists ($pathtocheck ))
{
$i++
$pathtocheck = $filepath + $filename + $i;
}
// your code for file write will be here
// this code will check is there file exist if not while will break otherwise it will continue till no file like FileNam1 ,FileNam2 and so on ...
I am having some difficulty with reading info from a text file. Is it possible to use php and get one line at a time, and compare that line to a variable, one character at a time? Every time I add the character searching algorithm it messes up. or does the file reading only do full files/lines/character
ex:
$file=fopen("text/dialogue.txt","r") or exit("unable to open dialogue file");
if($file == true) {
echo "File is open";
fgets($file);
$c = "";
while(!feof($file)) {
$line = fgets($file)
while($temp = fgetc($line)) {
$c = $c . $temp;
//if statement and comparrison
}
}
} else {
echo "File not open";
}
fclose($file);
You may use php file function to read a file line by line
<?php
$lines = file("myfile.txt");
foreach($lines as $line){
## do whatever you like here
echo($line);
}
?>
Please check php manual
http://php.net/manual/en/function.file.php