First off, this is an exact duplicate of these four questions:
Highlight the difference between two strings in PHP
JavaScript based diff utility
How to do text DIFF using PHP?
Calculate text diffs in PHP
It seems as though times have changed since these questions were first asked and I am wondering what is a good tool now-a-days for this sort of comparison? I have looked at (additionally to those questions):
https://github.com/nuxodin/diff_match_patch-php
http://pear.php.net/package/Text_Diff
https://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php
http://www.raymondhill.net/finediff/viewdiff-ex.php
But all of the ones I get are either unmantained now or seem a little dodgy in that they are not used that much (and some even hint that they are not very performant) and the PEAR one worries me. I hate to install PEAR for one little module not only that but it seems like throwing a brick through my own window to install it for such a small module in comparison to PEAR in general not only that but the module has been superseded and placed on a different channel (dunno why?). I would use the PEAR version if it is my only choice but I want to use the upto date package.
Does anyone know of a well used and currently maintained or built in function (even if it is a PHP extension) text diff for PHP and/or JavaScript (JQuery as well)?
Ok so it has been a while.
I actually decided to look around at what other people use and stumbled upon what Yii ( http://www.yiiframework.com ) uses.
They actually use the PEAR module for their text_diff and they use it in its new form on the horde channel. It seems that text_diff is now a horde project but you can just as easily integrate a version of it into your application and that is what Yii does by default (it comes pre-bundled with a version of it).
So I searched around a bit to find out how they used it and how to get into it and I came across:
public function actionDiff()
{
Yii::import('gii.components.TextDiff');
$model=$this->prepare();
if(isset($_GET['id']) && isset($model->files[$_GET['id']]))
{
$file=$model->files[$_GET['id']];
if(!in_array($file->type,array('php', 'txt','js','css')))
$diff=false;
elseif($file->operation===CCodeFile::OP_OVERWRITE)
$diff=TextDiff::compare(file_get_contents($file->path), $file->content);
else
$diff='';
$this->renderPartial('/common/diff',array(
'file'=>$file,
'diff'=>$diff,
));
}
else
throw new CHttpException(404,'Unable to find the code you requested.');
}
In CCodeGenerator for their Gii module ( http://www.yiiframework.com/doc/api/1.1/CCodeGenerator/ ). The important part is where they actually hook into the PEAR module:
$diff=TextDiff::compare(file_get_contents($file->path), $file->content);
By reading in the contents of two files which produces a diffed output.
Originally I did not want to use PEAR because of the bloat but this module is quite slim for a fully featured text_diff so I have decided to go with this. Not only that but, at the moment, it is the only text_diff module that has truly worked for me so I am keeping with the best, even if the best is quite memory hungry.
Have you tried one of Philippe's two solutions on this thread?
Quoted here:
In PHP. array_diff compares the first against the second array and
returns the difference.
$a1 = str_split('abcdefghijklmnop');
$a2 = str_split('abcdefghi');
echo join('', array_diff($a1, $a2)); // jklmnop
This will work as well:
$s1 = 'abcdefghijklmnop';
$s2 = 'abcdefghi';
echo str_replace(str_split($s2), '', $s1); // jklmnop
This could handle $s2 = 'ghiabcdef'; as well because str_replace() is fed with an
array, not a string.
Related
I am trying to apply a spell check to users' queries using a similar system to Google's "Did you mean: " using PHP.
Is there a way to do this with a plugin or API? If not, what are your suggestions?
Possible Simplified Code?
API
<?php
function checkSpelling($query) {
//Boolean where false value means a word is spelt wrong in string
return file_get_contents("http://foo.com/?q=$query");
}
function getSuggestions($query) {
//data with suggestions for word
return file_get_contents("http://foo.com/?q=$query");
}
if (!checkSpelling(foo)) {
echo getSuggestions(foo);
}
?>
Plugin
<?php
require("plugin.php");
//plugin functions similar to the functions above are defined already
if (!checkSpelling(foo)) {
echo getSuggestions(foo);
}
?>
NOTE: Pspell is not an option because I have PHP 5.X.X and am unable to install it on the server.
NOTE: PHP Spell Check does not have the disired interface.
Using Levenshtein Distance would be the first solution that come to mind and I would expect a hybrid approach of auto-complete, a common misspelling keyword set and then Levenshtein and/or SOUNDEX would get you in the usability ballpark that you're looking for. And yeah, it's a bit of a project.
Another piece of advice that comes to mind with things like this is to ask yourself. "What is it that I'm really trying to do?"
Often times a fullblown Google grade solution may be like sandblasting a soup cracker because your use case isn't theirs. If the goal is getting Visitor A to Information B in a nice easy way, they're are a number of ways to accomplish that that may be simpler and/or better for you instead of trying to reverse engineer something verbatim.
I have a php script. I want to check the php version compatibility that each function of this script has.
For example the script has the hash() function. If we look at php.net site it says that this function was added (PHP 5 >= 5.1.2, PECL hash >= 1.1).
So assuming that this script has only this function we say that it is compatible with php 5.1.2 and onwards. Is there any software tool that can scan the script and tell you the changelog of every function and possibly gives you the lowest possible score e.g. (php version 4.3 and on)? It is a bit tedious to check manually every function in the script.
Thank you in advance
As PHP supports dynamic function/method names, just searching through the source code would not give reliable results.
Example:
$function = 'strpos';
$result = $function(...);
You might use xdebug function traces together with a 100% test coverage. This could give you all function names which had been called during a test suite run with 100% coverage - meaning all code has run. But even this isn't reliable as you would have to make sure, that your test suite covered all possible dynamic function names what is impossible. (assuming the max length of a function name is unlimited)
My final answer is: this isn't reliably possible.
I have a PHP program using MySQL that I will be making open-source, including a simple installer, and I want to make it as easy to install on any server with PHP4 or 5 and MySQL 4 as possible.
I've included an installer to make it user-friendly, but I need to know what are the things I can do to make it most likely to install on every server.
I'll start: I've made sure to use full PHP tags (not short) like this <?php ?> and to make sure all variables are declared prior to using them, like so $nVar = (isset($_POST['nVar']) ? $_POST['nVar'] : NULL);.
What other best practices should be incorporated in a PHP app for the best cross-server compatability?
Just a few hints, from the top of my head
The class { __constructor } is deprecated.
Dont use GLOBAL
Use split and join
Watch out for file magic byte recognition functions
The get_class get_parent_class alphanumerical changed to accept camelcasing - use strtolower on returned value before comparing
I'm working on some code that reads from a socket, and it goes wrong when it gets a certain large input. I went to add a unit test for this, before fixing it, but got stuck because I cannot mock fread (and the other PHP built-in functions I'm using such as fsockopen, feof, etc.).
In simple terms my problem is that this code fails with "Fatal error: Cannot redeclare fgets() ...":
function fgets($fp){
return "xxx";
}
I realize I could create a socket wrapper class, that my real code uses, and then I could create a mock object for that wrapper class. But that is The Tail Wagging The Dog, and I can think of reasons it is a bad idea, beyond just the principle of the thing. (E.g. Making code more complex, efficiency, having to refactor code not under test yet.)
So, my question is how can I replace the built-in fgets() implementation with my own, within a unit test? (Or, if you want to think outside the box, the question can be phrased as: how can I control the string that a call to fgets($socket) returns, when $socket is the return value from a call to fsockopen?)
ASIDE
Installing apd, as required by the correct answer, is hard work; it was last released in 2004, and does not support php 5.3 out of the box. No Ubuntu package for it and also pecl install apd failed. So here are the procedures to install it (these are for ubuntu 10.04) (all done as root):
pecl download apd
tar xzf apd-1.0.1.tgz
cd apd-1.0.1
phpize
./configure
# Do edits (see below)
make install
See https://bugs.php.net/bug.php?id=58798 for the patch you need to do. NB. there is only one line you really have to change, so you can do it by hand, as follows: open php_apd.c in a text editor, go to line 967, and replace the CG(extended_info) = 1 line with this one:
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
Finally, you need to add a php.ini entry to activate it. See http://php.net/manual/en/apd.installation.php
If you don't have access to APD or Runkit but are using namespaces, try this: https://stackoverflow.com/a/5337635/664108 (Answer in link refers to time() but it makes no difference)
Have a look at these:
bool rename_function ( string $original_name , string $new_name )
bool override_function ( string $function_name , string $function_args , string $function_code )
Change fsockopen to fopen to do mock, and don't change any other functions.
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
to
$fp = fopen("/path/to/your/dummy_data_file");
I blogged about my experiences which contains full working code showing how to use override_function to achieve the desired goal; both file reading and socket reading. I won't repeat that whole article here, but will just point out how you have to use the functions:
Use rename_function to give a name to the old, original function, so
we can find it later.
Use override_function to define the new behaviour
Use rename_function to give a dummy name to __overridden__
Step 1 is critical if you want to be able to restore the original behaviour afterwards.
In the Food For Thought section at the end I show an alternative approach that I think is more robust, and therefore I think it is safer for replacing file functions when using phpUnit. It creates a permanent function replacement who's default behaviour is to forward to the built-in function. It then checks parameters (the resource $handle in this case) to decide if it is being called on a stream we want different behaviour for. (I think you could call this an example of the Chain Of Responsibility design pattern.)
Is there a way to remove function alias in PHP?
I can rename my function but it would be nice to use name "fetch".
Problem:
I just tested the following code and it appears to work for me, but perhaps it is because I don't have the mysqli library installed. I would test it because it might be more contextual than your IDE will have you believe. It seems to be a method for mysqli, but it might not be a global function.
<?php
function fetch(){
echo 'Hello world!';
}
fetch();
No.
(Short of recompiling the PHP binary)
This is more of a function of the IDE than the actual language... Some IDEs may give you that ability... I don't even know if recompiling the PHP binary (as Alan Storm suggested) would help since sometimes the stuff is hardcoded into the IDE / use the PHP docs online
For completeness sake: Normally, no, this can not be done. However: this can be done using a PECL extension called "runkit".
Runkit is described as "For all those things you probably shouldn't have been doing anyway", and allows you to basically tear out the innards of PHP from within PHP itself. Replacing built-in functions, undefining constants, unloading classes - suddenly everything is possible. And you should really question what you are doing if you ever feel you need it - odds are what you are doing violates some principles that are there for very good reasons, you just don't know them yet. I've never found a situation where using Runkit was a genuinely Good Idea.
Oh, in order to remove built-in functions you'll specifically need to enable this capability in your php.ini
(have fun!)