Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure ob_tidyhandler dynamically?

The PHP tidy extension has a function ob_tidyhandlerDocs that works with PHP output bufferingDocs as a callback, e.g.:

ob_start('ob_tidyhandler');

I know that Tidy has a lot of configuration settingsDocs, however I am hitting a road block to setup default configuration options for that output buffer callback.

Most of Tidy's PHP function refer to a tidy document or object, however with the output buffering that one is not accessible.

There is a configuration setting tidy.default_config, however that is not change-able at runtime, so it is not very dynamic.

Does anybody know if configuring the callback dynamically is possible at all? I remember I wrote a callback my own, collected all output and repaired it with a call to tidy_repair_stringDocs which accepts configuration as an array. But I thought it would be nice to not need to do that and just pass the configuration along for the output buffer.

like image 604
hakre Avatar asked Jul 24 '12 10:07

hakre


People also ask

What is Ob_start () and Ob_end_flush () in PHP?

While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer. The contents of this internal buffer may be copied into a string variable using ob_get_contents(). To output what is stored in the internal buffer, use ob_end_flush().

What does Ob_start () mean?

Definition and Usage The ob_start() function creates an output buffer. A callback function can be passed in to do processing on the contents of the buffer before it gets flushed from the buffer. Flags can be used to permit or restrict what the buffer is able to do.

What is use of Ob_end_clean in PHP?

The ob_end_clean() function deletes the topmost output buffer and all of its contents without sending anything to the browser.

What is the use of Ob_clean?

The ob_clean() function deletes all of the contents of the topmost output buffer, preventing them from getting sent to the browser.


1 Answers

I've had a quick look at the code for the tidy extension, and there is a way to change the configuration for the output buffer handler.

That said, it is not a nice way. It is exploiting a feature of the code which obviously may change in future versions.

The function that handles the buffer processing is php_tidy_output_handler and on line 1191 it calls the macro TIDY_SET_DEFAULT_CONFIG.

If tidy.default_config is not set, then the macro does nothing. If it is set then the configuration file is read from disk and the options are parsed.

Since the configuration file is loaded during the parsing of the output buffer, it is possible to modify the configuration file from your PHP script before parsing begins.

This means you have to make tidy.default_config = /file/writable/by/php and dynamically update this file to contain the options you require. (I told you it was not a nice way).


I can immediately see a problem with this. There is a potential race condition.

If two scripts require different options, and both are executed at the same time, there is the potential for one of the scripts to receive the wrong configuration.

The file is obviously not designed to be changed ad-hocly - and as you can probably follow from the extension code, there is no other available path to inject configuration options, since the options are specific to the document.

  • A new TidyDoc is created.
  • Couple of config flags set + default_config loaded.
  • Buffer is parsed.

Sorry, it feels like in the end I am just delivering bad news.

Your best solution may be to go with a custom ob_start callback where you have full control over the document options.

Edit:

Had a bit of a brainstorm and tried a few things to get around this. Everything has been met with failure.

I tried registering a custom stream wrapper to return per-script values, and set tidy.default_config = tidy://config. It turns out that stream wrappers are not resolved by the config loader and this does not work.

One thing I have not been able to test correctly is the per-directory configuration .user.ini or the [PATH=] ini section. These are both only available with the CGI/FastCGI SAPI (not FPM). I suspect this probably doesn't help you either.

like image 147
Leigh Avatar answered Oct 06 '22 18:10

Leigh