when this sample web page loads, it checks cached file from /cache folder. If there is no cached file, it calls ob_start() and creates a .html cache file. Problem is this caching process is working everytime even I have not called ob_start(). Please advise me. Thank you.
// class file
function check_cache($dynamic_url) {
$cache_file = $this->cache_folder.md5($dynamic_url).$this->cache_ext;
if ((file_exists($cache_file)) && (time() - $this->cache_time < filemtime($cache_file))) {
// ob_start('ob_gzhandler');
readfile($cache_file);
ob_end_flush();
exit();
}
else {
//ob_start('ob_gzhandler');
}
}
function create_cache($dynamic_url) {
$cache_file = $this->cache_folder.md5($dynamic_url).$this->cache_ext;
$fp = fopen($cache_file, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush();
}
and I call this class from
$cache->check_cache(get_full_url());
<h1>Today is <?php echo date('Y-m-d h:i:s'); ?></h1>
$cache->create_cache(get_full_url());
I think that your cache is still created because of your create_cache calling fopen no matter what the output buffer is started or not. Therefore, should check your output buffer status before do fopen, as follows:
function create_cache($dynamic_url) {
if (ob_get_level() > 0) {
$cache_file = $this->cache_folder.md5($dynamic_url).$this->cache_ext;
$fp = fopen($cache_file, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush();
}
}
You can use ob_get_level or ob_get_status: http://php.net/manual/en/function.ob-get-status.php
Related
I am trying to use a visitor count. I have made it so it works without flock, but are trying to make it work with flock. I don't really understand where I should use flock, but have tried implement it in a file called VisitorCount. Now I don't get any result and the website turns blank.
What should I think about when using flock?
<?php
require "visitorCount.php";
incrementVisitorCount();
header("Content-Type: text/plain");
echo getVisitorCount();
?>
<?php
$file = fopen("visitor-count.txt", "w+");
function incrementVisitorCount() {
$visitorCount = getVisitorCount();
if(flock($file, LOCK_EX)) {
file_put_contents("visitor-count.txt", $visitorCount + 1);
fflush($file);
flock($file, LOCK_UN);
} else {
echo "Couldn't get the lock!";
}
fclose($file);
}
function getVisitorCount() {
$visitorCount = trim(file_get_contents("visitor-count.txt"));
return $visitorCount;
}
?>
6php version it's works, on 7.2php it's works too but not currently what can be there wrong? don't offer use another like phpfastcache i need this method.
<?php
//settings
$cache_ext = '.html'; //file extension
$cache_time = 10; //Cache file expires afere these seconds (1 hour = 3600 sec)
$cache_folder = 'cache/'; //folder to store Cache files
$ignore_pages = array('', '');
$dynamic_url = 'http://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']; // requested dynamic page (full url)
$cache_file = $cache_folder.md5($dynamic_url).$cache_ext; // construct a cache file
$ignore = (in_array($dynamic_url,$ignore_pages))?true:false; //check if url is in ignore list
if (!$ignore && file_exists($cache_file) && time() - $cache_time < filemtime($cache_file)) { //check Cache exist and it's not expired.
ob_start('ob_gzhandler'); //Turn on output buffering, "ob_gzhandler" for the compressed page with gzip.
readfile($cache_file); //read Cache file
echo '<!-- cached page - '.date('l jS \of F Y h:i:s A', filemtime($cache_file)).', Page : '.$dynamic_url.' -->';
ob_end_flush(); //Flush and turn off output buffering
exit(); //no need to proceed further, exit the flow.
}
//Turn on output buffering with gzip compression.
ob_start('ob_gzhandler');
######## Your Website Content Starts Below #########
?>
<?php
######## Your Website Content Ends here #########
if (!is_dir($cache_folder)) { //create a new folder if we need to
mkdir($cache_folder);
}
if(!$ignore){
$fp = fopen($cache_file, 'w'); //open file for writing
fwrite($fp, ob_get_contents()); //write contents of the output buffer in Cache file
fclose($fp); //Close file pointer
}
ob_end_flush(); //Flush and turn off output buffering
?>
i have a zip file and user can only access the file once they complete their payment and i am using paypal payment gateway,so i have applied the condition that the download link will only be visible to user once they have completed their transaction,but my requirement id this that user must not be able to open this zip file through url,but once they complete their transaction then the user can download the file from the link given by me 1.e
Download Zip, i have hosted my website on godaddy.
<?php
session_start();
if(isset($_SESSION['item_name']) && $_SESSION['item_name']!=''){
if($_SESSION['item_name']=='Android Apps'){
?>
Download Zip
<?php }
} else{
header('Location: abc.com/rrr/form1.html');
}
?>
use the following methods in your code. this way you don't need to redirect the user to the real url of zip file. you can serve the zip from any php script e.g. your payment confirmation page can redirect to a script with a random token which expires after first download/time-
//call this method for sending download file.
function sendDL($filename)
{
header("Content-length:".filesize($filename));
header('Content-Type: application/x-gzip'); // ZIP file
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="download.gz"');
header('Content-Transfer-Encoding: binary');
ob_end_clean(); //output buffer cleanup
_readfileChunked($filename);
}
function _readfileChunked($filename, $retbytes=true) {
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
$cnt =0;
// $handle = fopen($filename, 'rb');
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
consider these like utility methods. from any script which doesn't push any other out (ie. no echo) the first method can be used for sending a file to user. call that like this
<?php
$dlToken = $_GET['dltoken'];
$filename = '/path/to/secret.file';
//Check if this dlToken is in database/memcache or not. and if yes its expired or not.
if($yes)
{
sendDL($filename);
}
else
{
sendNack();
}
function sendNack()
{
echo '___DATA_NOT_FOUND___'; //NOTICE this is the only echo in this script. and it means we are not sending the file after all.
//header("HTTP/1.0 404 Not Found");
exit();
}
//put the two methods there
function sendDL($filename)
{
//...
}
function _readfileChunked($filename, $retbytes=true)
{
//...
}
?>
At the page/script where you give the download link. generate a random unique token. you can use uniqid or mt_rand or both. save this in database along with a timestamp value (which you can use in download script mentioned above to check if the token has expired). create a download url with that token as something like following
download.php?file=test.zip&token=the_unique_token×tamp=unix_timestamp
I have the following code in a PHP page. Some times when I delete the cache2.html file, I expect the php to recreate it and the next person will get the cache2.html instead of executing the php code. I get the following warning some times on the page and no content. Is it because of multiple users accessing the php concurrently? If so, How do I fix it? Thank you.
Warning: include(dir1/cache2.html) [function.include]: failed to
open stream: No such file or directory in
/home/content/54/site/index.php on line 8
<?php
if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); else ob_start();
$cachefile = "dir1/cache2.html";
if (file_exists($cachefile)) {
include($cachefile); // output the contents of the cache file
} else {
/* HTML (BUILT USING PHP/MYSQL) */
$cachefile = "dir1/cache2.html";
$fp = fopen($cachefile, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_flush(); // Send the output to the browser
}
?>
Calls to file_exists() are themselves cached, so it's likely you're getting a return value of true even after the file is deleted. See:
http://us.php.net/manual/en/function.clearstatcache.php
So, you could do:
clearstatcache();
if (file_exists($cache)) {
include($cache);
} else {
// generate page
}
Alternatively, you could do something like this:
if (file_exists($cache) && #include($cache)) {
exit;
} else {
// generate page
}
Or better, if you're deleting the cache file from within a PHP process, then just call clearstatcache() after you delete the file.
i have read a bit around in the internet about the php cache.
at the moment i am using, this system to cache my pages:
This is putted on the start of the page
<?php
// Settings
$cachedir = 'cache/'; // Directory to cache files in (keep outside web root)
$cachetime = 600; // Seconds to cache files for
$cacheext = 'html'; // Extension to give cached files (usually cache, htm, txt)
// Ignore List
$ignore_list = array(
'addedbytes.com/rss.php',
'addedbytes.com/search/'
);
// Script
$page = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // Requested page
$cachefile = $cachedir . md5($page) . '.' . $cacheext; // Cache file to either load or create
$ignore_page = false;
for ($i = 0; $i < count($ignore_list); $i++) {
$ignore_page = (strpos($page, $ignore_list[$i]) !== false) ? true : $ignore_page;
}
$cachefile_created = ((#file_exists($cachefile)) and ($ignore_page === false)) ? #filemtime($cachefile) : 0;
#clearstatcache();
// Show file from cache if still valid
if (time() - $cachetime < $cachefile_created) {
//ob_start('ob_gzhandler');
#readfile($cachefile);
//ob_end_flush();
exit();
}
// If we're still here, we need to generate a cache file
ob_start();
?>
MY HTML CODE Goes here .............
and the code below is at the footer of my page.
<?php
// Now the script has run, generate a new cache file
$fp = #fopen($cachefile, 'w');
// save the contents of output buffer to the file
#fwrite($fp, ob_get_contents());
#fclose($fp);
ob_end_flush();
?>
There are some things that i need and this code dont have them :
gzip
the expired cache is not autodeleted after it expire.
Also wanted to ask, if this code is secure to use , if some one can suggest a better one or something to improve the current code it will be just great
Thank you fro reading this post.
Best Regards
Meo
….
// Show file from cache if still valid
if (time() - $cachetime < $cachefile_created) {
//ob_start('ob_gzhandler');
echo gzuncompress(file_get_contents($cachefile));
//ob_end_flush();
exit();
} else {
if(file_exists($cachefile) && is_writable($cachefile)) unlink($cachefile)
}
….
and
// Now the script has run, generate a new cache file
$fp = #fopen($cachefile, 'w');
// save the contents of output buffer to the file
#fwrite($fp, gzcompress(ob_get_contents(), 9));
#fclose($fp);
ob_end_flush();
?>
Use ob_start("ob_gzhandler"); to initiate gzipped buffering (it'll take care of determining if the client can actually accept/wants gzipped data and adjust things accordingly).
To delete the cached files:
if (time() - $cachetime < $cachefile_created) {
#readfile($cachefile);
//ob_end_flush();
exit();
} else {
unlink($cachefile);
exit();
}
But there can be delay or maybe error when the file is being written and someone requests for that page. You should use flock to overcome such problems as mentioned at Error during file write in simple PHP caching
Something like this at the end of page
<?php
$fp = #fopen($cachefile, 'w');
if (flock($fp, LOCK_EX | LOCK_NB)) {
fwrite($fp, gzcompress(ob_get_contents(), 9));
flock($fp, LOCK_UN);
fclose($fp);
}
ob_end_flush(); ?>