Php очистка кэша браузера
для моего сайта у меня есть следующие правила htaccess:
Я только что обновил свой сайт, и он выглядел странно, пока я не очистил свой кэш. Как заставить браузер клиента очистить кэш после обновления, чтобы пользователь мог видеть изменения?
вы можете заставить браузеры кэшировать что-то, но
вы не можете заставить браузеры очистить свой кэш.
таким образом, единственный (AMAIK) способ-использовать новый URL для ваших ресурсов. Что-то вроде версии.
как говорили другие ответы, изменение URL-адреса является хорошим методом перебора кэша, однако это много работы, чтобы пройти через больший сайт, изменить все URL-адреса, а также переместить файлы.
аналогичный метод состоит в том, чтобы просто добавить параметр версии в строку URL, которая является случайной строкой / номером или номером версии, и нацелить только измененные файлы.
например, если вы измените свои сайты CSS, и он выглядит шатким, пока вы не сделаете обновление силы, просто добавьте ?ver=1.1 к импорту CSS в начале файла. Это для браузера другой файл, но вам нужно только изменить импорт, а не фактическое местоположение или имя файла.
отлично работает и для файлов javascript.
у меня есть твоя проблема.
хотя мы можем полностью очистить кэш браузера клиента, но вы можете добавить код в свое приложение, чтобы ваши последние изменения отразились на браузере клиента.
вы не можете заставить браузеры очистить кэш.
ваш .html-файл, похоже, будет повторно загружен раньше, поскольку он истекает через 10 дней. Что вам нужно сделать, это обновить .HTML-файл и переместить все файлы в новую папку, например version-2/ или добавьте идентификатор версии к каждому файлу, например mypicture-2.jpg . Затем вы ссылаетесь на эти новые файлы в своем .html-файл и браузер будут загружать их снова, потому что местоположение изменилось.
вы можете сказать, что браузер никогда не кэширует ваш сайт, вставляя следующий код в заголовок
и чтобы предотвратить кэш JS, css, вы можете использовать инструмент для минимизации и запутывания скриптов, которые должны генерировать случайное имя файла каждый раз. Это заставило бы браузер перезагрузить их с сервера.
надеюсь, что это помогает.
вы можете установить "доступ плюс 1 секунд" , и таким образом он будет обновляться при следующем входе пользователя на сайт. Оставьте настройку на один месяц.
самое прямое-добавить filetime в запрос. например!--1-->
управление версиями по дате.
в моем случае я много меняю конкретный файл JS, и мне нужно, чтобы он был в его последней версии во всех браузерах, где используется.
У меня нет определенного номера версии для этого файла, поэтому Я просто хэш-текущую дату и время (час и минуту) и передать его как номер версии:
Мне нужно, чтобы быть загружены каждую минуту, но вы можете решить, когда он должен быть перезагружен.
теперь следующее не поможет вам с файлами, которые уже кэшированы, но двигаясь вперед, вы можете использовать следующее, Чтобы легко заставить запрос получить что-то новое, без изменения фактического имени файла.
конечно, чем выше в структуре папок вы делаете такой подход, чем больше вы выбиваете вещей из кэша с помощью простого изменения.
так, например, если вы храните весь CSS и JavaScript вашего сайта в основных папка
тогда вы можете начать ссылаться на него как" assets-XXX " в своем html и использовать правило, подобное этому, чтобы выгнать все содержимое активов из кэша.
обратите внимание, что если вы пойдете с этим, после того, как он будет работать, измените 302 на 301, а затем кэширование начнется. Когда это 302, он не будет кэшировать на уровне браузера, потому что это временное перенаправление. Если вы сделаете это таким образом, вы можете увеличить срок действия по умолчанию до 30 дней для всех активов, так как вы можете легко выбить вещи из кэша, просто изменив имя папки на странице входа в систему.
изменить имя .файл CSS Загрузите страницу, а затем снова измените файл на исходное имя, которое он работает для меня.
Ситуация следующая: был сайт www.mysite.com оставил много разных куков, кэшированных картинок и стилей css. Сайт обновился, но кэшированная информация у пользователей мешает нормальной работе (особенно google chrome 29). Если отчистить историю+кэш+куки всё отлично начинает работать. Можно ли как то принудительно при первом заходе заставить браузер удалить информацию по этому сайту, а далее уже кэшировать "как всегда"?
Я читал про это, в таком случае он не будет кэшироваться вообще, а мне в идеале хотелось бы "отчистить" а потом кэшировать как всегда
Пройдитесь по домам ваших посетителей и почистите тогда им кэш :) Как вы представляете себе - все пользователи зайдут к вам одновременно в тот период, когда у вас сервер будет отдавать эти хедеры? Раскиньте мозгами - "маркируйте" очищенных с помощью куков - зашел пользователь? Зашел. Есть кука? Нет. Тогда получи с хедером и поставь новую "маркер"-куку. Следующий раз зайдет - проверяйте "маркер"-куку. Есть? Отлично - не шлите больше хедеров. Продержите такое на время, пока не почувствуете, что пора завязывать с этим механизмом и все "проапдейтились".
2 ответа 2
Или слать header в страницах (как-то в таком стиле)
У вас, это то не беда, чтоб на сайте отображались css правильно (как я понял вы его меняете периодически и это ломает отображение сайта) надо всего лишь сделать все время новый адрес загрузки css вот так:
и все браузер будет думать что файл css все время новый и верстка ломаться не будет
а вот у меня другая проблема, на сайте есть авторизация и иногда случается что на некоторые страницы (закрытые не авторизованным пользователям) зайти не получается, дело в том, что браузер в этих случаях даже и не пытается проверить авторизацию и сразу выкидывает на главную, как не аторизованного пользователя. Причем если очистить кеш браузера сразу все работает правильно!
я уже кучу сайтов с авторизацией сделал и такого ниразу не встречал, что мне делать? я просто в шоке.
P.S. кеш браузере запретил всеми способами: через php заголовки, через .htaccess и обычными метатегами nocach
Функция сбрасывает весь кеш. После вызова opcache_reset() все скрипты будут заново загружены, скомпилированы и помещены в кеш после их следующего вызова. Функция сбрасывает только кеш в памяти, не затрагивая файловый кеш.
Список параметров
У этой функции нет параметров.
Возвращаемые значения
Возвращает true , если кеш сброшен или false , если не используется.
Смотрите также
User Contributed Notes 7 notes
My workaround to clear cache via CLI is create a bash script like this:
put it in /usr/local/bin/opcache-clear and make it executable.
When I want to clear cache I simply run "opcache-clear" inside terminal.
In some (most?) systems PHP's CLI has a separate opcode cache to the one used by the web server or PHP-FPM process, which means running opcache_reset() in the CLI won't reset the webserver/fpm opcode cache, and vice-versa.
For longer php scripts: opcache_reset() will obtain a lock and it will reset the cache only after the script has ended, after which the lock is released.
Calling opcache_reset() multiple times or any other opcache manipulation method, like opcache_invalidate(), after calling opcache_reset() in a single script is not useful: while opcache_reset() holds the lock, other opcache methods will return false and they will have zero effect on the cache.
Although the opcache manipulation methods have no effect during this lock, opcache does recache scripts corresponding to the opcache.revalidate_freq setting, provided that opcache.validate_timestamps is switched on.
To keep the cache up to date, use opcache_invalidate() when modifying single php files. Use opcache_reset() for bigger changes and only at the end of a php script.
So, I thought I'd share something that might benefit those looking for a way to reset opcache in CLI.
As an example in my case, I'm running a Laravel app with a router script with the built-in web server for local development. I enabled opcache with the following run configuration:
/path/to/php.exe -d zend_extension=php_opcache.dll -d opcache.enable_cli=1 -d opcache.memory_consumption=128 -d opcache.max_accelerated_files=10000 -d opcache.validate_timestamps=0 -d opcache.save_comments=0 -t project_path/public/ server.php
This is basically what artisan serve is doing behind the scenes, anyway, except without the opcache part.
I have some file watchers setup to detect changes and executes the following upon said change(s):
/path/to/php.exe -d zend_extension=php_opcache.dll -d opcache.enable_cli=1 -r "opcache_reset();"
The key is ensuring that you're enabling opcache in CLI. I've been using this for some time, so I can attest to this being a viable solution without needing to create a script to execute somewhere in the document root, etc.
I'm only referring to Laravel as an example of why I chose to explore options for solving this problem. This should translate to any scenario a developer would need to utilize opcache in their project(s) while using the built-in web server.
For people who have difficulties with constants and opcache_reset().
If you include a file with constant and do an opcache_reset() in the same file, you'll probably have some error like :
"Notice: Constant already defined"
The trick is to call opcache_reset() in an isolated file, then include another file that include the file with constants.
File a.php
opcache_reset ();
include 'b.php'
?>
File b.php
include 'constants.php' ;
?>
File constants.php
define ( 'MY_CONST' , 'abcdef' );
?>
With this trick, the opcache will be reset in a.php and when b.php will be included, the constants will not be in cache anymore.
Для обеспечения большей производительности при использовании функций stat() , lstat() или любой другой функции, перечисленных в приведённом ниже списке, PHP кеширует результаты их выполнения. Однако, в некоторых случаях вам может потребоваться очистка этого кеша. Например, когда ваш скрипт несколько раз проверяет состояние одного и того же файла, который может быть изменён или удалён во время выполнения скрипта, вы можете захотеть очистить кеш состояния. В этом случае необходимо использовать функцию clearstatcache() для очистки в PHP кешированной информации об указанном файле.
Обратите внимание, что PHP не кеширует информацию о несуществующих файлах. Так что, если вы вызовете file_exists() на несуществующем файле, она будет возвращать false до тех пор, пока вы не создадите этот файл. Если же вы создадите файл, она будет возвращать true , даже если затем вы его удалите. Однако, функция unlink() очистит данный кеш автоматически.
Замечание:
Данная функция кеширует информацию об определённых файлах, поэтому имеет смысл вызывать clearstatcache() только в том случае, если вы совершаете несколько операций с одним и тем же файлом и не хотите получать кешированную информацию об этом файле.
Список параметров
Нужно ли также очищать кеш realpath.
Очистить кеш realpath только для определённого имени файла; используется только в том случае, если у параметра clear_realpath_cache установлено значение true .
Возвращаемые значения
Функция не возвращает значения после выполнения.
Примеры
function get_owner ( $file )
$stat = stat ( $file );
$user = posix_getpwuid ( $stat [ 'uid' ]);
return $user [ 'name' ];
>
$format = "UID @ %s: %s\n" ;
printf ( $format , date ( 'r' ), get_owner ( $file ));
chown ( $file , 'ross' );
printf ( $format , date ( 'r' ), get_owner ( $file ));
clearstatcache ();
printf ( $format , date ( 'r' ), get_owner ( $file ));
?>
Результатом выполнения данного примера будет что-то подобное:
User Contributed Notes 7 notes
Not documented, but seems like clearstatcache() is clearing the cache only for the process it is being called from. I have 2 PHP scripts running simultaneously, and the first one does call clearstatcache(), but still the second one deadlocks, unless I call clearstatcache() in it too:
unlink() does not clear the cache if you are performing file_exists() on a remote file like:
if ( file_exists ( "ftp://ftp.example.com/somefile" ))
?>
In this case, even after you unlink() successfully, you must call clearstatcache().
clearstatcache() does not canonicalize the path. clearstatcache(true, "/a/b/c") is different from clearstatcache(true, "/a/b//c").
Note that this function affects only file metadata. However, all the PHP file system functions do their own caching of actual file contents as well. You can use the "realpath_cache_size = 0" directive in PHP.ini to disable the content caching if you like. The default content caching timeout is 120 seconds.
Content caching is not a good idea during development work and for certain kinds of applications, since your code may read in old data from a file whose contents you have just changed.
Just to make this more obvious (and so search engines find this easier):
If you do fileops of any kind outside of PHP (say via a system() call), you probably want to clear the stat cache before doing any further tests on the file/dir/whatever. For example:
// is_dir() forces a stat call, so the cache is populated
if( is_dir ( $foo ) ) system ( "rm -rf " . escapeshellarg ( $foo ));
if( is_dir ( $foo ) ) // . will still be true, even if the rm succeeded, because it's just
// reading from cache, not re-running the stat()
>
>
?>
Pop a clearstatcache() after the system call and all is good (modulo a bit of a performance hit from having a cleared stat cache :-( ).
Definition of $filename parameter let's you think that it expects the filename only but it works if you give the path + filename also.
It should be more clear about this.
On Linux, a forked process inherits a copy of the parent's cache, but after forking the two caches do not impact each other. The snippet below demonstrates this by creating a child and confirming outdated (cached) information, then clearing the cache, and getting new information.
if ( is_dir ( $target )) die( "Delete $target before running.\n" );
>
echo "Creating $target .\n" ;
mkdir ( $target ) || die( "Unable to create $target .\n" );
report ( $target ); // is_dir($target) is now cached as true
echo "Unlinking $target .\n" ;
rmdir ( $target ) || die( "Unable to unlink $target .\n" );
// This will say "yes", which is old (inaccurate) information.
report ( $target );
if (( $pid = pcntl_fork ()) === - 1 ) < die( "Failed to pcntl_fork.\n" ); >
elseif ( $pid === 0 ) // child
report ( $target , '> ' );
echo "> Clearing stat cache.\n" ;
clearstatcache ();
report ( $target , '> ' );
> else // parent
sleep ( 2 ); // move this to the child block to reverse the test.
report ( $target , '> ' );
clearstatcache ();
report ( $target , '> ' );
>
Функция очищает системный буфер вывода PHP, при этом всё содержимое буфера отправляется в браузер пользователя (с некоторыми исключениями), независимо от используемого бекенда PHP (CGI, веб-сервер и т.д.).
flush() не сможет переопределить схему буферизации вашего веб-сервера и никак не влияет на буферизацию браузера на стороне клиента. Функция также не влияет на механизм буферизации пользовательского PHP-кода. Это означает, что ob_flush() должен быть вызван перед flush() , чтобы очистить выходные буферы, если они используются.
Некоторые серверы, особенно под управлением Win32, будут по-прежнему продолжать буферизировать вывод вашего скрипта до передачи результатов в браузер.
Серверные модули для Apache, такие как mod_gzip, могут сами выполнять буферизацию, поэтому flush() не приводит к немедленной передаче данных клиенту.
Список параметров
У этой функции нет параметров.
Возвращаемые значения
Функция не возвращает значения после выполнения.
Смотрите также
User Contributed Notes 36 notes
This will show each line at a time with a pause of 2 seconds.
(Tested under IEx and Firefox)
if ( ob_get_level () == 0 ) ob_start ();
echo "
Line to show." ;
echo str_pad ( '' , 4096 ). "\n" ;
This is what I use to turn off pretty much anything that could cause unwanted output buffering and turn on implicit flush:
@ apache_setenv ( 'no-gzip' , 1 );
@ ini_set ( 'zlib.output_compression' , 0 );
@ ini_set ( 'implicit_flush' , 1 );
for ( $i = 0 ; $i < ob_get_level (); $i ++) < ob_end_flush (); >
ob_implicit_flush ( 1 );
?>
If it still fails though, keep in mind that Internet Explorer and Safari have a 1k buffer before incremental rendering kicks in, so you'll want to output some padding as well.
I would like to point out that there is a function to replace ob_flush and flush. If you set ob_implicit_flush(true); at the top of the page it will automatically flush any echo or print you do in the rest of the script.
Note that you still need a minimum amount of data to come through the browser filter. I would advice using str_pad($text,4096); since this automatically lenghtens the text with spaces to 4 KB which is the minimum limit when using FireFox and linux.
I hope this helps you all out a bit.
This is an extention of Rusty's comment below:
After sitting here for hours trying to make IE6 flush data out in the middle of a page (with it working perfectly in Firefox), I finally figured out the problem. IE will not display flushed data (even if it has it) unless the table that contains it is complete.
Every new element you want IE to display must not be in ANY kind of table at all. You must end all your tables.
For a Windows system using IIS, the ResponseBufferLimit takes precedence over PHP's output_buffering settings. So you must also set the ResponseBufferLimit to be something lower than its default value.
For IIS versions older than 7, the setting can be found in the %windir%\System32\inetsrv\fcgiext.ini file (the FastCGI config file). You can set the appropriate line to:
ResponseBufferLimit=0
For IIS 7+, the settings are stored in %windir%\System32\inetsrv\config. Edit the applicationHost.config file and search for PHP_via_FastCGI (assuming that you have installed PHP as a FastCGI module, as per the installation instructions, with the name PHP_via_FastCGI). Within the add tag, place the following setting at the end:
responseBufferLimit="0"
So the entire line will look something like:
Alternatively you can insert the setting using the following command:
%windir%\system32\inetsrv\appcmd.exe set config /section:handlers "/[name='PHP_via_FastCGI'].ResponseBufferLimit:0"
Hi all.
Been scratching my head over data NOT flushed to IE (6) even though I tried strpad 4096 chars, all headers OK, TABLE and no TABLE, flush and ob_flush - still a blank page. Tried adding a sleep(1) before flushing - and everything worked as a charm.
When using PHP with mode CGI/FastCGI there is a new buffer (initiated by mod_fcgid with a default size of 65536 bytes). That causes `flush()` and `ob_flush()` not working as expected with implicit_flush(true).
Setting "OutputBufferSize 0" in mod_fcgid config resolves the issue.
Hope it helps !
Not the other way around, because it wont work.
Like IE, Safari needs a fair amount of data before it'll display anything, actually more than explorer. The following code works for me in Firefox and Safari, and should work in IE as well.
for( $i = 0 ; $i < 40000 ; $i ++)
echo ' ' ; // extra spaces
>
// keeps it flowing to the browser?
flush ();
// 50000 microseconds keeps things flowing in safari, IE, firefox, etc
usleep ( 50000 );
?>
This code came from a comment on a blog discussing browser functionality with flush();
After searching through the PHP site, google and various forums, not finding a solution to my script not outputting anything while calling flush and ob_flush, I thought of trying to tell PHP to call:
before starting echo'ing. It worked like a charm. I couldn't find any references to this, so I hope this note will help someone in the future.
I've spent days trying to figure out why flush didn't work all of a sudden, while it used to work perfectly. Apparently, it was McAfee Spamkiller that caused problems. Disabling it didn't work, I had to completely remove it. Hope this helps someone.
It is a bit complicated to work with the funktion flush() and you have to experiment with it a bit.
So if you design a site which has a timeloop at the end that calls a other site via a form data input (Data Submit) you have
to give something out to the buffer to get that new site loaden quick.
$instant = gettimeofday ();
$timenow = $instant [ "sec" ]; //Start Time
//timeloop(e.g. for security_save after 30 min)
while ( 1 ) " ; //Useless (only to quickload next
//or same Site when do a switch)
flush (); //giveout buffer
$instant = gettimeofday ();
$timeactual = $instant [ "sec" ]; //get Actual Time in Secs
$flag =(( $timeactual > $timenow + $diff )? 1 : 0 ); //$diff=switchTime
if ( $flag ) < what_do_at_switch_Time (); //Sec.Save etc.etc.
$timenow = $timeactual ; > //Set new Start Time
sleep ( 5 ); //Or so. (Important)
> //End of while-Loop
?>
So you can programm a security save or other function in your site and if you do a switch the upload of the new or same site (the called site) works.
combining some ideas i was finally able to get a long running script to give me real time feedback on what it was doing. this was a wamp setup with php running as cgi. i'm pretty sure that apache just wasn't sending any of the buffered output because it was trying to be helpful. also trying to be helpful, i hope this example solution helps someone.
// thx mandor at mandor
ini_set ( 'max_execution_time' , 0 );
ini_set ( 'implicit_flush' , 1 );
ob_implicit_flush ( 1 );
echo 'doing something' ; my_flush ();
sleep ( 5 );
echo 'doing something else' ; my_flush ();
sleep ( 5 );
echo 'finally done - hooray' ;
function my_flush () // following matt at hevanet's lead
for ( $i = 0 ; $i < 10000 ; $i ++) echo ' ' ;
ob_flush ();
flush ();
>
I had a bunch of problems trying to get flush working on my windows box, I finally found a solution after reading everyones here and it not working.
1) Set output_buffering = 0
2) Set zlib.output_compression = 0
I then used Wireshark to monitor network packets, and indeed the server was pusing the data, but the browser was not displaying it.. So it was a browser buffer issue (I am on Firefox 13)
For me I needed to send about 1k of data before it would display the data. To do this I added more header information..
In php.ini I set default_charset = "utf-8"
And that was enough to give me enough for the buffer issue.
You can also try doing
echo str_repeat(" ", 1024), "\n";
at the start of the script.
hope this helps
If flush() function does not work. You must set next options in php.ini like:
--[code]--
output_buffering = Off
;output_handler =
zlib.output_compression = Off
;zlib.output_handler =
--[^code^]--
If things does not work you must view headers from the server and check `Server` string.
In my case, as the frontend was Nginx webserver and Apache work as backend.
Accordingly, buffering must be disabled in Nginx config file.
To stop buffering you must add next string to config file:
and restart Nginx daemon. More information about configuration you find in documentation on the nginx website.
If you're not explictly using the buffering functions, then ob_flush() is only necessary if output buffering is turned on in your php.ini file.
flush() is only necessary if implicit_flush is turned off in your php.ini file. Setting implicit_flush to on will remove the need for all these flush() calls, but it's generally only good in an extremely controlled environment. Turning on implicit_flush in a production environment can be bad.
On Windows xampp 1.3 with php 4.3.4 is use this functions
to force a flush.
function dummyErrorHandler ( $errno , $errstr , $errfile , $errline ) <
>
function forceFlush () <
ob_start ();
ob_end_clean ();
flush ();
set_error_handler ( "dummyErrorHandler" );
ob_end_flush ();
restore_error_handler ();
>
?>
ob_end_flush generates a warning, which is supressed, using the dummy-errorhander. You could also use @, but then nusphere will also print the warning.
These values can be appended to the directive, e.g. or in ProxyPass and ProxyPassMatch lines.
The mod_proxy_fcgi documentation for 2.4 does not document this, but it is available in the 2.5 or trunk documentation.
Regarding buffering by browser you can use:
Works for me in Firefox 60 ESR.
This helped me getting flushing to work.
Using apache with deflate.
Turning compression off for this script: (add it somewhere at the top of the script)
apache_setenv('no-gzip', '1');
However, this only works if php is running as a module rather than a cgi-extension and safe mode must be disabled.
You can also turn the compression off for a directory by making a .htaccess file and adding the following entry:
mod_gzip_on Off
However that affects the whole directory.
Hope I could help.
I had the same problems with sending a javascript after the content has been sent to the browser (the script updates the content of an iframe).
Two solutions work for me:
- add enough data (i.e.: extra dummy text like spaces) or,
- echo the '' tag at the end of the page
Note, that for the latter to work one should:
- turn of output_buffering in php.ini and either:
* turn on implicit_flush in its php.ini or,
* call ob_implicit_flush(); at the beginning of a script
I preferr echoing the '