{"id":15939425,"url":"https://github.com/ghostwriter/handrail","last_synced_at":"2025-10-14T02:21:47.350Z","repository":{"id":257813013,"uuid":"868638989","full_name":"ghostwriter/handrail","owner":"ghostwriter","description":"Safeguard PHP functions from redeclaration conflicts","archived":false,"fork":false,"pushed_at":"2025-09-27T14:31:23.000Z","size":773,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"0.1.x","last_synced_at":"2025-09-27T16:21:51.561Z","etag":null,"topics":["composer","composer-plugin","conflicts","functions","ghostwriter","handrail","php","plugin","redeclaration","safeguard"],"latest_commit_sha":null,"homepage":"https://github.com/ghostwriter/handrail","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghostwriter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["ghostwriter"]}},"created_at":"2024-10-06T22:13:33.000Z","updated_at":"2025-09-27T14:31:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"40ad5757-0367-4d71-bd2a-3663a7cf59c9","html_url":"https://github.com/ghostwriter/handrail","commit_stats":{"total_commits":171,"total_committers":1,"mean_commits":171.0,"dds":0.0,"last_synced_commit":"2e29388988b7f39196bf8c6ea96dbb940768ddbb"},"previous_names":["ghostwriter/handrail"],"tags_count":5,"template":false,"template_full_name":"ghostwriter/package-template","purl":"pkg:github/ghostwriter/handrail","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fhandrail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fhandrail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fhandrail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fhandrail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghostwriter","download_url":"https://codeload.github.com/ghostwriter/handrail/tar.gz/refs/heads/0.1.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fhandrail/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279017682,"owners_count":26086126,"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","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["composer","composer-plugin","conflicts","functions","ghostwriter","handrail","php","plugin","redeclaration","safeguard"],"created_at":"2024-10-07T06:04:29.695Z","updated_at":"2025-10-14T02:21:47.344Z","avatar_url":"https://github.com/ghostwriter.png","language":"PHP","funding_links":["https://github.com/sponsors/ghostwriter"],"categories":[],"sub_categories":[],"readme":"# Handrail\n\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/ghostwriter?label=Sponsor+@ghostwriter/handrail\u0026logo=GitHub+Sponsors)](https://github.com/sponsors/ghostwriter)\n[![Automation](https://github.com/ghostwriter/handrail/actions/workflows/automation.yml/badge.svg)](https://github.com/ghostwriter/handrail/actions/workflows/automation.yml)\n[![Supported PHP Version](https://badgen.net/packagist/php/ghostwriter/handrail?color=8892bf)](https://www.php.net/supported-versions)\n[![Downloads](https://badgen.net/packagist/dt/ghostwriter/handrail?color=blue)](https://packagist.org/packages/ghostwriter/handrail)\n\nSafeguard your PHP code by wrapping function declarations in `if (!function_exists())` blocks.\n\nEnsures that functions are only declared if they do not already exist, preventing redeclaration conflicts.\n\n### Star ⭐️ this repo if you find it useful\n\nYou can also star (🌟) this repo to find it easier later.\n\n## Installation\n\nYou can install the package via composer:\n\n``` bash\ncomposer require ghostwriter/handrail\n```\n\n### Example\n\nBefore running Handrail:\n\n```php\n\u003c?php\n\nfunction exampleFunction() {\n    // some code\n}\n\nfunction anotherFunction() {\n    // more code\n}\n```\n\nAfter running Handrail:\n\n```php\n\u003c?php\n\nif (!function_exists('exampleFunction')) {\n    function exampleFunction() {\n        // some code\n    }\n}\n\nif (!function_exists('anotherFunction')) {\n    function anotherFunction() {\n        // more code\n    }\n}\n```\n\n### Configuration\n\nTo configure the paths or files to scan, create a composer `extra` configuration in your `composer.json`:\n\n```json\n{\n    \"extra\": {\n        \"ghostwriter/handrail\": {\n            \"disable\": false,\n            \"packages\": [\n                \"vendor/package\"\n            ],\n            \"files\": [\n                \"vendor/amphp/amp/src/functions.php\",\n                \"relative/path/to/file.php\"\n            ]\n        }\n    }\n}\n```\n\n- **`disable`**: (default: `false`) A boolean flag to enable or disable Handrail.\n- **`files`**: (default: `[]`) An array of files to scan for function declarations.\n- **`packages`**: (default: `[]`) An array of Composer packages to scan for function declarations.\n\n## Usage\n\n### Automatic Execution\n\nAfter installing and configuring Handrail, we will automatically hook into Composer’s lifecycle events (`post-install-cmd` and `post-update-cmd`) after Composer installs or updates packages.\n\n```bash\ncomposer install\n```\n\n```bash\ncomposer update\n```\n\n### Manual Execution\n\nYou can also run Handrail manually using the following Composer command:\n\n```bash\ncomposer handrail\n```\n\n## Advanced Usage\n\n### Running Handrail Programmatically\n\nHandrail provides an API for programmatic execution within PHP scripts:\n\n```php\nuse Ghostwriter\\Handrail\\Handrail;\n\nHandrail::new()-\u003eguard($phpFile);\n```\n\n\n### Credits\n\n- [Nathanael Esayeas](https://github.com/ghostwriter)\n- [All Contributors](https://github.com/ghostwriter/handrail/contributors)\n\n### Thanks\n\n- [Yevhen Sidelnyk](https://github.com/rela589n) for the [inspiration](https://github.com/rela589n/knowledge-base/blob/a72b3071b770253dc61d03d8d2849e47a8229bc7/PHP/Psalm%20in%20a%20separate%20composer.json.md).\n\n### Changelog\n\nPlease see [CHANGELOG.md](./CHANGELOG.md) for more information on what has changed recently.\n\n### License\n\nPlease see [LICENSE](./LICENSE) for more information on the license that applies to this project.\n\n### Security\n\nPlease see [SECURITY.md](./SECURITY.md) for more information on security disclosure process.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghostwriter%2Fhandrail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghostwriter%2Fhandrail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghostwriter%2Fhandrail/lists"}