Using Enchant with PHP on Windows - Part 1
PHP 5.3 introduced us to some new bundled extensions, including Enchant. The Enchant extension is a binding for the Enchant library.
Note: Before PHP 5.3, Enchant was available as optional extension through PECL. This article however only covers the setup and usage of the bundled extension in PHP 5.3
This short tutorial gives an introduction to setting up and using this new extension for your PHP projects.
What is Enchant?
Enchant is a library that provides a generic interface to third-party spell-checking APIs (Application Programming Interfaces) and ABIs (Application Binary Interfaces). And this is mainly where the power of Enchant lies in.
Normally if you want to spell-check English and French texts, you'd use the same spell-checking API (e.g. Aspell), because implementing multiple spell-checking libraries would require that you, the developer, knows how to use those specific APIs, each API bringing different methods of checking and correction. But that also means if Aspell, while very good in spell-checking English texts, isn't very strong in spell-checking French texts, while for example Ispell is strong in spell-checking French texts, you cannot bring the same spell-checking quality to the user as he should be able to.
When you use Enchant, the same programming interface can be used for different spell-checking libraries. We are now able to use Aspell for English texts and Ispell for French texts without adding specific Ispell API-calls for checking French texts.
Follow along to see how easy this can be, even on Windows!
Installing Enchant
Installing Enchant is as easy as enabling the extension in your active php.ini. Go to the line that says:
;extension=php_enchant.dll
And change it to:
extension=php_enchant.dll
Now restart your webserver to see these changes live. But that's not all, some more stuff comes to it. Read the next paragraph to find out more!
Using Enchant
As with every extension, PHP provides documentation. For Enchant the documentation can be found on http://www.php.net/enchant
Note: Not every function of the Enchant extension is currently documented. A look inside the Enchant PECL source shows some functions and constants like enchant_broker_get_dict_path which are still on the php.net documentation TODO-list all as far as I noticed.
Nonetheless, a lot of documentation about Enchant can be found at other resources. Since the first day I started programming, I gathered information from as much resources as possible, think of "How to do this in Java" while actually needing to do something in Ruby, or "How to install this in Perl" when needing documentation on installing Ada libraries. This is something that helped me in this situation too; try searching Google on Enchant, PHP and Windows or Ispell and MySpell for that matter and see how many awesome results you get /sarcasm. But lets talk about that in a minute in the next paragraph.
First I want to show you the basic usage of Enchant and how it doesn't work by default in Windows (don't know about Linux/*BSD?) Below is the example taken from php.net:
<?php
$tag = 'en_US';
$r = enchant_broker_init();
$bprovides = enchant_broker_describe($r);
echo "Current broker provides the following backend(s):\n";
print_r($bprovides);
$dicts = enchant_broker_list_dicts($r);
print_r($dicts);
if (enchant_broker_dict_exists($r,$tag)) {
$d = enchant_broker_request_dict($r, $tag);
$dprovides = enchant_dict_describe($d);
echo "dictionary $tag provides:\n";
$wordcorrect = enchant_dict_check($d, "soong");
print_r($dprovides);
if (!$wordcorrect) {
$suggs = enchant_dict_suggest($d, "soong");
echo "Suggestions for 'soong':";
print_r($suggs);
}
enchant_broker_free_dict($d);
} else {
}
enchant_broker_free($r);
?>
By default PHP will not go beyond the line saying
if (enchant_broker_dict_exists($r,$tag)) {
We will have to install some dictionaries first.
Installing dictionaries
As I already mentioned above, before you can actually use Enchant's spelling suggestions and other material you have to install some dictionaries. Funny enough, no Windows documentation exists for this yet and even the Linux/*BSD part isn't documented at php.net.
Fortunatly, there are some other resources we can gain information from. First on, I'll show you what I tried before.
In the last paragraph I said not all Enchant's functions were documented at php.net yet, so I looked at the source of the extension, and found a function I thought it'll help me, named enchant_broker_get_dict_path. The function signature for that function is:
string enchant_broker_get_dict_path(resource broker, int dict_type)
This function requires 2 parameters, first the broker resource (created using enchant_broker_init()) and the dict_type, a non-documented constant value. There are 2 possible values for dict_type as indicated by the source, the first one is ENCHANT_ISPELL and the second ENCHANT_MYSPELL, the 2 default included spell-checking providers.
Calling this function however triggered a 500 error on my Apache and crashed my CLI instance of PHP (bug?).
This function already triggerd my brain, as how does it actually know where my dictionaries are installed in the first place? A lot of searches pointed me to this post on Google Groups talking about pyenchant (remember my note on this before?)
So there is also a function allowing me to set this path! Browsing the source again, I stumbled upon enchant_broker_set_dict_path:
bool enchant_broker_set_dict_path(resource broker, int dict_type, string value)
Calling this function above enchant_broker_get_dict_path, fixed the crashing/500 error I got before and actually allowed me to set my dictionary paths:
enchant_broker_set_dict_path($broker, ENCHANT_MYSPELL, 'C:\PHP\enchant\MySpell'); enchant_broker_set_dict_path($broker, ENCHANT_ISPELL, 'C:\PHP\enchant\Ispell');
Note: these directories do not exist by default, so you have to create them, but you can create them anywhere since it doesn't matter where you actually store these dictionaries as long as PHP can access them.
Now we can actually install the dictionaries. Dictionaries can be found at many places, I used the Slovak dictionary found on the Mozilla Wiki's L10n:Dictionaries page.. Extract the downloaded zip-file to your dictionary path (so you get something like C:\PHP\enchant\MySpell\sk_SK.aff and C:\PHP\enchant\MySpell\sk_SK.dic) and refresh your page. As you can see, the dictionary you extracted is now ready to use.
A working example!
Since I already mentioned in the previous paragraph I installed the Slovak (sk_SK) dictionary for the MySpell provider in C:\PHP\enchant\MySpell\, I will just show you the code I use to test all of this; the code I used to get a spelling suggestion for the word "soong" (the word the PHP manual also uses in its example):
<?php
$broker = enchant_broker_init();
$tag = 'sk_SK';
enchant_broker_set_dict_path($broker, ENCHANT_MYSPELL, 'C:\PHP\enchant\MySpell');
if (enchant_broker_dict_exists($broker, $tag)) {
$dict = enchant_broker_request_dict($broker, $tag);
$word = 'soong';
$isCorrectlySpelled = enchant_dict_check($dict, $word);
if ($isCorrectlySpelled !== true) {
$suggestions = enchant_dict_suggest($dict, $word);
echo nl2br(print_r($suggestions, true));
} else {
echo 'The word is correctly spelled!';
}
}
enchant_broker_free($broker);
?>
If you followed all my instructions above the following should be on your screen right now:
Array ( [0] => song )
Conclusion
It took me a lot of time figuring out how this all worked and I hope I helped anyone reading this article looking for some information on how to set all this up. In the next part I'll go up and do some more funky stuff using Enchant. Stay tuned!