{"id":13562537,"url":"https://github.com/tigitz/php-spellchecker","last_synced_at":"2025-05-14T19:06:04.975Z","repository":{"id":34100936,"uuid":"164334482","full_name":"tigitz/php-spellchecker","owner":"tigitz","description":"🐘🎓📝 PHP Library providing an easy way to spellcheck multiple sources of text by many spellcheckers","archived":false,"fork":false,"pushed_at":"2025-04-09T16:25:50.000Z","size":576,"stargazers_count":308,"open_issues_count":2,"forks_count":31,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-14T23:17:56.181Z","etag":null,"topics":["misspell","php","php-spellchecker","pspell","spellcheck","spellchecker","spelling","spelling-checker","spelling-correction"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tigitz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-06T18:33:54.000Z","updated_at":"2025-03-04T09:18:45.000Z","dependencies_parsed_at":"2024-01-14T03:46:11.323Z","dependency_job_id":"7ef82a4f-76c1-4f72-b56f-8c4d49e745a0","html_url":"https://github.com/tigitz/php-spellchecker","commit_stats":{"total_commits":128,"total_committers":13,"mean_commits":9.846153846153847,"dds":0.7265625,"last_synced_commit":"05700c43cecb3116624343303458c090d7b6ea19"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigitz%2Fphp-spellchecker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigitz%2Fphp-spellchecker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigitz%2Fphp-spellchecker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigitz%2Fphp-spellchecker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tigitz","download_url":"https://codeload.github.com/tigitz/php-spellchecker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248975329,"owners_count":21192210,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["misspell","php","php-spellchecker","pspell","spellcheck","spellchecker","spelling","spelling-checker","spelling-correction"],"created_at":"2024-08-01T13:01:09.703Z","updated_at":"2025-04-14T23:18:12.246Z","avatar_url":"https://github.com/tigitz.png","language":"PHP","readme":"\u003ch1 align=\"center\"\u003ePHP-Spellchecker\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://i.imgur.com/C8hHwW9.png\" alt=\"PHP-Spellchecker\" width=\"300\" height=\"300\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/tigitz/php-spellchecker/actions\"\u003e\u003cimg src=\"https://img.shields.io/github/check-runs/tigitz/php-spellchecker/master?logo=github\u0026style=flat-square\" alt=\"Build Status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/tigitz/php-spellchecker/branch/master\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/github/tigitz/php-spellchecker/master.svg?style=flat-square\u0026logo=codecov\" alt=\"Code coverage\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://scrutinizer-ci.com/g/tigitz/php-spellchecker/?branch=master\"\u003e\u003cimg src=\"https://img.shields.io/scrutinizer/g/tigitz/php-spellchecker.svg?style=flat-square\u0026logo=scrutinizer\" alt=\"Code coverage\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://gitter.im/php-spellchecker/php-spellchecker\"\u003e\u003cimg src=\"https://img.shields.io/gitter/room/tigitz/php-spellchecker.svg?style=flat-square\" alt=\"PHP-Spellchecker chat room\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://choosealicense.com/licenses/mit/\"\u003e\u003cimg src=\"https://img.shields.io/github/license/tigitz/php-spellchecker.svg?style=flat-square\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eCheck misspellings from any text source with the most popular PHP spellchecker.\u003c/p\u003e\n\n\n------\n# About\n\nPHP-Spellchecker is a spellchecker abstraction library for PHP. By providing a unified interface for many different spellcheckers, you’re able to swap out spellcheckers without extensive rewrites.\n\nUsing PHP-Spellchecker can eliminate vendor lock-in, reduce technical debt, and improve the testability of your code.\n\n# Features\n\n- 🧐 Supports many popular spellcheckers out of the box: [Aspell][aspell], [Hunspell][hunspell], [Ispell][ispell], [PHP Pspell][pspell], [LanguageTools][languagetools], [JamSpell][jamspell] and [MultiSpellchecker][multispellchecker] [(add yours!)][spellchecker_custom]\n- 📄 Supports different text sources: file system [file][filesource]/[directory][directory], [string][php-string], and [multi-source][multisource] [(add yours!)][source_custom]\n- 🛠 Supports text processors: [MarkdownRemover][markdownremover] [(add yours!)][textprocessor_custom]\n- 🔁 Supports misspelling handlers: [EchoHandler][echohandler] [(add yours!)][custom_handler]\n- ➰ Makes use of generators to reduce memory footprint\n- ⚖ Flexible and straightforward design\n- 💡 Makes it a breeze to implement your own spellcheckers, text processors and misspellings handlers\n- 💪 Runs tests against real spellcheckers to ensure full compatibility\n\n**PHP-Spellchecker** is a welcoming project for new contributors.\n\nWant to make **your first open source contribution**? Check the [roadmap](#roadmap), pick one task, [open an issue](https://github.com/tigitz/php-spellchecker/issues/new) and we'll help you go through it 🤓🚀\n\n# Install\n\nVia Composer\n\n```sh\ncomposer require tigitz/php-spellchecker\n```\n\n# Usage\n\n[Check out the documentation](https://tigitz.github.io/php-spellchecker) and [examples](https://github.com/tigitz/php-spellchecker/tree/master/examples)\n\n## Using the spellchecker directly\n\nYou can check misspellings directly from a `PhpSpellcheck\\Spellchecker` class and process them on your own.\n\n```php\n\u003c?php\n// if you made the default aspell installation on your local machine\n$aspell = Aspell::create();\n\n// or if you want to use binaries from Docker\n$aspell = new Aspell(new CommandLine(['docker','run','--rm', '-i', 'starefossen/aspell']));\n\n$misspellings = $aspell-\u003echeck('mispell', ['en_US'], ['from_example']);\nforeach ($misspellings as $misspelling) {\n    $misspelling-\u003egetWord(); // 'mispell'\n    $misspelling-\u003egetLineNumber(); // '1'\n    $misspelling-\u003egetOffset(); // '0'\n    $misspelling-\u003egetSuggestions(); // ['misspell', ...]\n    $misspelling-\u003egetContext(); // ['from_example']\n}\n```\n\n## Using the `MisspellingFinder` orchestrator\n\nYou can also use an opinionated `MisspellingFinder` class to orchestrate your spellchecking flow:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://i.imgur.com/n3JjWgh.png\" alt=\"PHP-Spellchecker-misspellingfinder-flow\"\u003e\n\u003c/p\u003e\n\nFollowing the well-known [Unix philosophy](http://en.wikipedia.org/wiki/Unix_philosophy):\n\u003e Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.\n\n```php\n\u003c?php\n// My custom text processor that replaces \"_\" by \" \"\n$customTextProcessor = new class implements TextProcessorInterface\n{\n    public function process(TextInterface $text): TextInterface\n    {\n        $contentProcessed = str_replace('_', ' ', $text-\u003egetContent());\n\n        return $text-\u003ereplaceContent($contentProcessed);\n    }\n};\n\n$misspellingFinder = new MisspellingFinder(\n    Aspell::create(), // Creates aspell spellchecker pointing to \"aspell\" as it's binary path\n    new EchoHandler(), // Handles all the misspellings found by echoing their information\n    $customTextProcessor\n);\n\n// using a string\n$misspellingFinder-\u003efind('It\\'s_a_mispelling', ['en_US']);\n// word: mispelling | line: 1 | offset: 7 | suggestions: mi spelling,mi-spelling,misspelling | context: []\n\n// using a TextSource\n$inMemoryTextProvider = new class implements SourceInterface\n{\n    public function toTexts(array $context): iterable\n    {\n        yield new Text('my_mispell', ['from_source_interface']);\n        // t() is a shortcut for new Text()\n        yield t('my_other_mispell', ['from_named_constructor']);\n    }\n};\n\n$misspellingFinder-\u003efind($inMemoryTextProvider, ['en_US']);\n//word: mispell | line: 1 | offset: 3 | suggestions: mi spell,mi-spell,misspell,... | context: [\"from_source_interface\"]\n//word: mispell | line: 1 | offset: 9 | suggestions: mi spell,mi-spell,misspell,... | context: [\"from_named_constructor\"]\n```\n\n# Roadmap\n\nThe project is still in its initial phase, requiring more real-life usage to stabilize its final 1.0.0 API.\n\n## Global\n\n- [ ] Add a CLI that could do something like `vendor/bin/php-spellchecker \"misspell\" Languagetools EchoHandler --lang=en_US`\n- [ ] Add asynchronous mechanism to spellcheckers.\n- [ ] Make some computed misspelling properties optional to improve performance for certain use cases (e.g., lines and offset in `LanguageTools`).\n- [ ] Add a language mapper to manage different representations across spellcheckers.\n- [ ] Evaluate `strtok` instead of `explode` to parse lines of text, for performance.\n- [ ] Evaluate `MutableMisspelling` for performance comparison.\n- [ ] Wrap `Webmozart/Assert` library exceptions to throw PHP-Spellchecker custom exceptions instead.\n- [ ] Improve the `Makefile`.\n\n## Sources\n\n- [ ] Make a `SourceInterface` class that's able to have an effect on the used spellchecker configuration.\n- [ ] `League/Flysystem` source.\n- [ ] `Symfony/Finder` source.\n\n## Text processors\n\n- [ ] Markdown - Find a way to keep the original offset and line of words after stripping.\n- [ ] Add PHPDoc processor.\n- [ ] Add HTML Processor ([inspiration](https://github.com/mekras/php-speller/blob/master/src/Source/Filter/HtmlFilter.php)).\n- [ ] Add XLIFF Processor ([inspiration](https://github.com/mekras/php-speller/blob/master/src/Source/XliffSource.php)).\n\n## Spell checkers\n\n- [ ] Cache suggestions of already spellchecked words (PSR-6/PSR-16?).\n- [ ] Pspell - Find way to compute word offset.\n- [ ] LanguageTools - Evaluate [HTTPlug library][httplug] to make API requests.\n- [x] Pspell - find way to list available dictionaries.\n- [x] Add [JamSpell](https://github.com/bakwc/JamSpell#http-api) spellchecker.\n- [ ] Add [NuSpell](https://github.com/nuspell/nuspell) spellchecker.\n- [ ] Add [SymSpell](https://github.com/LeonErath/SymSpellAPI) spellchecker.\n- [ ] Add [Yandex.Speller API](https://yandex.ru/dev/speller/doc/dg/concepts/api-overview-docpage/) spellchecker.\n- [ ] Add [Bing Spell Check API](https://docs.microsoft.com/en-us/azure/cognitive-services/bing-spell-check/overview) spellchecker.\n\n## Handlers\n\n- [ ] MonologHandler\n- [ ] ChainedHandler\n- [ ] HTMLReportHandler\n- [ ] XmlReportHandler\n- [ ] JSONReportHandler\n- [ ] ConsoleTableHandler\n\n## Tests\n\n- [ ] Add or improve tests with different text encoding.\n- [ ] Refactor duplicate Dockerfile content between PHP images.\n\n\n# Versioning\n\nWe follow [SemVer v2.0.0](http://semver.org/).\n\nThere still are many design decisions that should be confronted with real-world usage before thinking about a v1.0.0 stable release:\n\n- Are `TextInterface` and `MisspellingInterface` really useful?\n- Is using generators the right way to go?\n- Should all the contributed spellcheckers be maintained by the package itself?\n- How to design an intuitive CLI given the needed flexibility of usage?\n- Is the \"context\" array passed through all the layers the right design to handle data sharing?\n\n# Testing\n\nSpell checkers come in many different forms, from HTTP API to command line tools. **PHP-Spellchecker** wants to ensure real-world usage is OK, so it contains integration tests. To run these, spellcheckers need to all be available during tests execution.\n\nThe most convenient way to do it is by using Docker and avoid polluting your local machine.\n\n## Docker\n\nRequires `docker` and `docker-compose` to be installed (tested on Linux).\n\n```sh\n$ make build # build container images\n$ make setup # start spellcheckers container\n$ make tests-dox\n```\n\nYou can also specify PHP version, dependency version target and if you want coverage.\n\n```sh\n$ PHP_VERSION=8.2 DEPS=LOWEST WITH_COVERAGE=\"true\" make tests-dox\n```\n\nRun `make help` to list all available tasks.\n\n## Environment variables\n\nIf spellcheckers execution paths are different than their default values (e.g., `docker exec -ti myispell` instead of `ispell`) you can override the path used in tests by redefining environment variables in the [PHPUnit config file](https://github.com/tigitz/php-spellchecker/blob/master/phpunit.xml.dist).\n\n# Contributing\n\nPlease see [CONTRIBUTING](https://github.com/tigitz/php-spellchecker/tree/master/examples).\n\n# Credits\n\n- Inspired by [php-speller](https://github.com/mekras/php-speller), [monolog](https://github.com/Seldaek/monolog) and [flysystem](https://github.com/thephpleague/flysystem)\n- [Philippe Segatori][link-author]\n- [All Contributors][link-contributors]\n\n# License\n\nThe MIT License (MIT). Please see [license file](https://github.com/tigitz/php-spellchecker/blob/master/LICENSE.md) for more information.\n\n**Logo**:\nElements taken for the final rendering are [Designed by rawpixel.com / Freepik](http://www.freepik.com).\n\n[link-author]: https://github.com/tigitz\n[link-contributors]: ../../contributors\n\n[aspell]: https://tigitz.github.io/php-spellchecker/docs/spellcheckers/aspell.html\n[hunspell]: https://tigitz.github.io/php-spellchecker/docs/spellcheckers/hunspell.html\n[ispell]: https://tigitz.github.io/php-spellchecker/docs/spellcheckers/ispell.html\n[languagetools]: https://tigitz.github.io/php-spellchecker/docs/spellcheckers/languagetools.html\n[jamspell]: https://tigitz.github.io/php-spellchecker/docs/spellcheckers/jamspell.html\n[pspell]: https://tigitz.github.io/php-spellchecker/docs/spellcheckers/php-pspell.html\n[multispellchecker]: https://tigitz.github.io/php-spellchecker/docs/spellcheckers/multispellchecker.html\n[spellchecker_custom]: https://tigitz.github.io/php-spellchecker/docs/spellcheckers/create-custom.html\n\n[echohandler]: https://tigitz.github.io/php-spellchecker/docs/misspellings-handlers/echohandler.html\n[custom_handler]: https://tigitz.github.io/php-spellchecker/docs/misspellings-handlers/create-custom.html\n\n[filesource]: https://tigitz.github.io/php-spellchecker/docs/text-sources/file.html\n[directory]: https://tigitz.github.io/php-spellchecker/docs/text-sources/directory.html\n[php-string]: https://tigitz.github.io/php-spellchecker/docs/text-sources/php-string.html\n[multisource]: https://tigitz.github.io/php-spellchecker/docs/text-sources/multisource.html\n[source_custom]: https://tigitz.github.io/php-spellchecker/docs/text-sources/create-custom.html\n\n[markdownremover]: https://tigitz.github.io/php-spellchecker/docs/text-processors/markdown-remover.html\n[textprocessor_custom]: https://tigitz.github.io/php-spellchecker/docs/text-processors/create-custom.html\n\n[httplug]: https://github.com/php-http/httplug\n","funding_links":[],"categories":["PHP"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigitz%2Fphp-spellchecker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftigitz%2Fphp-spellchecker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigitz%2Fphp-spellchecker/lists"}