PHP Tidy: tidy_setopt() alternative? - php

So I'm trying to tailor PHP's Tidy to my liking, but the problem is with the tidy_setopt() function.
I know tidy is installed and working just fine, and reading the PHP docs it says tidy_setopt() has been removed as of 2.0 (So since the ob callback is working perfectly I'm safe to assume I'm running Tidy 2.0+).
Here is the problem: There is no alternative function. I'm hoping there is a way to get around this so I can set the ob handler's settings up how I want them to without actually needing to edit a configuration file.
I'm sure my hosting will be willing to edit Tidy's configuration file if needed, but I'd rather not add to the barrage of support tickets I've been sending them for various reasons as it is.
If I need to create my own callback for output buffering I can do so (I see some possibly useful methods using the OO approach to tidy) but I'd rather have it as slim as possible.

Instead of using
tidy_setopt('indent', FALSE);
You should use
$config = array('indent' => FALSE);
$text = tidy_parse_string($text, $config, 'UTF8');
Also see Output Control Functions manual for "User defined callback function example"

Related

Having PHP site point to a different path than one that is in the code

I am running a PHP site on Windows using Wampserver. All throughout the site there is a hardcoded line such as:
$settings = parse_ini_file("/usr/local/apache2/myconfigs/settings.ini", true);
I know this is bad practice to begin with but it is out of my control.
When the site runs is there any possible way I can trick the site to point to C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini whenever the code is looking for /usr/local/apache2/myconfigs/settings.ini in the parse_ini_file function?
$settings = parse_ini_file(APACHE_INI_PATH, true);
// $settings = parse_ini_file("/usr/local/apache2/myconfigs/settings.ini", true);
This is a bit hackish but I think it's what you are looking for, so the trick here is to redefine the parse_ini_file function and make it ignore the invalid passed path ("/usr/local/apache2/myconfigs/settings.ini") and use your correct file instead.
This seems straightforward but a bit tricky since your new function should also call the original parse_ini_file function somehow, that's why you need to rename it first then override it
You will need PHP runkit extension enabled for this, have look at runkit_function_redefine and runkit_function_rename for reference.
Untested but should work, the code should be something around these lines :
runkit_function_rename('parse_ini_file','original_parse_ini_file');
runkit_function_redefine('parse_ini_file', function() {
original_parse_ini_file("C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini", true);
});
Make sure the code above is executed at the start of your application script and any parse_ini_file call should use your file instead of the hardcoded one.
If there is no single entry point to your application where you can put the code above, you can put it in a separate script and make PHP load before running any script via the auto_prepend_file setting in your settings.ini file, also make sure that runkit.internal_override is set to On since parse_ini_file is not a user defined function.
Hello please check this
runkit_function_rename('parse_ini_file','o_parse_ini_file');
runkit_function_redefine('parse_ini_file', function($p1,$p2) use($someCondition) {
if($someCondition)
o_parse_ini_file("C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini", true);
else
o_parse_ini_file($p1,$p2);
});
it can return
Call to undefined function runkit_function_rename()
to fix this error please read here
or here
If you don't want to do a find and replace as suggested by #cddoma, I propose that you create the directory /usr/local/apache2/myconfigs/ in your windows machine, and copy the file settings.ini from C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini to that directory.
Open your windows command line and enter the following
mkdir C:\usr\local\apache2\myconfigs\
copy C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini C:\usr\local\apache2\myconfigs\
you may be able to do this with a Symbolic link on Windows

Prevent exit() in third-party function from exiting?

I'm calling several functions (which I can't edit) in sequence, but some of the functions redirect the user, so I never get to the next one.
I'm calling a third-party function which has calls to wp_redirect() which I'm able to prevent, but then the next line is exit; which I can't figure out how get around.
I was hoping to get around it with the ob_ functions, but no luck so far.
Any suggestions, hacky or otherwise, will be hugely appreciated!
edit: I have an idea I haven't tried yet - somehow spawning off new processes to perform these tasks - what would be best way to do that, waiting for each to complete before moving on.
I believe is possible to get the source code of the php interpreter ... mess with the exit function and then recompile and install on the web server your new custom version of php ...
I'm afraid you just can't. There is an option to redefind native php function, see runkit_function_redefine.
But in the comments it also says:
language constructs
(eval, die, exit, isset, unset, echo etc.) which might be confused
with functions, cannot be renamed or redefined even with
runkit.internal_override.
You may be able to use runkit_function_redefine. You'll need to make sure you can modify internal functions in your php.ini file in order to be able to change native/internal functions.
I think the php.ini setting you need to ensure is switched on is runkit.internal_override.
I've not tested this.
However, since exit is a language construct I'm not even sure it's possible to get around it even with the above function.
In the end I went with using cURL to make three synchronous requests to a file with different GET params.
Throw an exception in wp_redirect, and wrap the code with try-catch statement, then check if the exception message contains the message you have set and return the response accordingly, I have used this hack with most plugins including woocommerce, ultimatemember etc...
example:
ob_start();
try{
whatever code....
}catch(\Exception $e){
}
echo ob_get_clean();

Count number of file requests triggered

Is it possible with PHP(5) or other Linux tools on an apache debian webserver to get the file requests a single http request made?
for performance reasons i would like to compare them with the cached "version" of my cake app.
non-cached that might be over 100 in some views.
cached only up to 10 (hopefully).
afaik there are 3 main file functions:
file_get_contents(), file() and the manual fopen() etc
but i cannot override them so i cannot place a logRequest() function in them.
is there any other way? attaching callbacks to functions? intercepting the file requests?
This suggestion does not seems intuitive, but you can take look on xdebug - function trace
Once you have xdebug installed and enabled, you can using all sort of configuration to save the profiling into a disk file and you can retrieve it later. Such as profiling results for different URL save into different disk file.
To monitoring file system related functions, you can do a parse of the text file(profiling results) and do a count of matchable functions (programmable or manually)
The way I would do it would be to create a custom function that wraps around the one you need.
function custom_file_get_contents($filename) {
$GLOBALS['file_get_contents_count']++;
return file_get_contents($filename);
}
And just replace all of your calls to file_get_contents with custom_file_get_contents. This is just a rudimentary example, but you get the idea.
Side note, if you want to count how many files your script has included (or required), see get_included_files()
You can use Xdebug to log all function calls
Those so-called "function traces" can be a help for when you are new to an application or when you are trying to figure out what exactly is going on when your application is running. The function traces can optionally also show the values of variables passed to the functions and methods, and also return values. In the default traces those two elements are not available.
http://www.xdebug.org/docs/execution_trace
Interesting question. I'd start with the stream_wrapper ... try to replace them with custom classes.
There is a pecl extention called ADB (Advanced PHP Debugger) that has tow functions that would be very useful for a cse like this - override_function() and rename_function(). You could do something like this:
rename_function('file_get_contents', 'file_get_contents_orig');
function file_get_contents($filename) {
logRequest();
return file_get_contents_orig($filename);
}
It looks like ADB is pretty easy to install, too.
See http://www.php.net/manual/en/book.apd.php

custom php function creation and install

I would like to know how to create a php function that can be installed in php
just like the already built in functions like :
rename
copy
The main point I would like to achieve is a simple php function that can be called from ANY php page on the whole host without needing to have a php function within the php page / needing an include.
so simply I would like to create a function that will work like this :
location();
That without a given input string will output the current location of the file via echo etc
Well, there are a couple of options here. One of them is to actually extend the language by writing an extension. You'd have to muck around with the PHP source code, write it in C, and deal with the Zend Engine internally. You probably wouldn't be able to use this on a shared host and it would be quite time consuming and probably not worth it.
What I would do is put all of your functions into a separate PHP file, say helper_functions.php. Now, go into your php.ini and add the directive: auto_prepend_file = helper_functions.php. This file should be in one of the directories specified in your include_path (that's a php.ini directive too).
What this does is basically automatically put include 'helper_functions.php'; on every script. Each and every request will have these functions included, and you can use them globally.
Read more about auto_append_file.
As others have said, there's probably an easier, better way to do most things. But if you want to write an extension, try these links:
http://docstore.mik.ua/orelly/webprog/php/ch14_01.htm
http://www.tuxradar.com/practicalphp/2/3/0
So you want to extend PHP's core language to create a function called location(), written in C, which could be done in PHP by:
echo __FILE__;
Right. Have fun doing that.

Storing, Updating, Retrieving settings for a PHP Application without a Database

I need to be able to store data for a php application in a file. I need to be able to do this without any sort of external dependencies other than PHP itself.
Here are the requirements I have:
Settings will not be updated/added/removed very often. So updating of settings does not have to be very efficient. However, I do want to be able to do this all through a PHP script, not through editing of files.
Settings will be read constantly, so reading of settings must be very efficient.
Settings are in a unique format, if I had them in an array it might be something like $Settings["Database"]["AccessSettings"]["Username"]["myDBUsername"]; $Settings["Database"]["AccessSettings"]["Password"]["myDBPassword"];
I would prefer to not have settings stored in arrays like I mentioned above. Instead I would prefer some access methods: getConfig("Database","Accesssettings","Username") would return 'myDBUsername'. The reason for this is I want to limit the variables I am storing in the global scope.
What would the best way of getting/retrieving these be?
Do the the hierarchy I was thinking possibly an xml file, but I wasn't sure what PHP was like for accessing xml files (particularly the fact that I need to be able to add, edit, and remove). If it should be XML what sort of xml access should I look into.
If it is another format, I would like some pointers to the right direction for what to look into for how to use that format.
Brian, parse_ini_file is what you need.
Ah, I missed the requirement that you'd be editing this via PHP.
In that case there is nothing native to PHP that you can use for this purpose. You'd have to roll your own.
You could save yourself a ton of time by simply using Zend_Config_Ini though. I know you state that you don't want to use anything else, but Zend Framework is structured to allow you to use whatever pieces of it you need. Zend_Config can be used on it's own. You can certainly just add these few classes to your project and let them handle your INI file parsing.
Here is an example using your samples above:
[config]
Database.AccessSettings.Username = myDBUsername
Database.AccessSettings.Password = myDBPassword
You would load and access this as simply as:
$config = new Zend_Config_Ini('/path/to/ini', 'config');
echo $config->Datbase->AccessSettings->Username; // prints "myDBUsername"
echo $config->Datbase->AccessSettings->Password; // prints "myDBPassword"
To edit and save your config you would use the following:
$config->Database->AccessSettings->Password = "foobar";
$writer = new Zend_Config_Writer_Ini(array('config' => $config,
'filename' => 'config.ini'));
$writer->write();
Edit
Not really sure why people are voting this down based on vog's misguided comments. It is very simple to make this writable by multiple persons by using an exclusive lock. Zend_Config_Writer uses file_put_contents to do it's writing, which has always supported the the LOCK_EX flag, which exclusively locks a file for writing. When using this flag, you cannot have multiple writers attempting to update the file at the same time.
To use this flag with Zend_Config_Writer it's as simple as follows:
$writer = new Zend_Config_Writer_Ini(array('config' => $config,
'filename' => 'config.ini'));
$writer->setExclusiveLock(true);
$writer->write();
An alternate syntax:
$writer = new Zend_Config_Writer_Ini();
$writer->write('config.ini', $config, true); // 3rd parameter is $exclusiveLock
If you're not hand editing, use serialized data.
Writing config using serialize:
file_put_contents('myConfig.txt', serialize($Settings));
Reading config using unserialize:
$Settings = unserialize(file_get_contents('myConfig.txt'));
You could write a class for modifying and getting values for this data using PHP magic functions __get() and __set().
If you are willing to drop in a library, you could use Spyc and have your configuration in a YAML file.
You could also use PHP's support for SQLite which would mean your database is just a file so no need for a DB server.
DBM files may not be a bad idea. PHP has built in support for the various DBM-file varieties:
http://www.php.net/manual/en/book.dba.php

Categories