{"id":17949325,"url":"https://github.com/gnikyt/with","last_synced_at":"2025-03-24T22:35:51.595Z","repository":{"id":6312415,"uuid":"7547317","full_name":"gnikyt/with","owner":"gnikyt","description":"A Python with-statement clone for PHP.","archived":false,"fork":false,"pushed_at":"2022-12-05T21:06:13.000Z","size":22,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-19T05:14:35.969Z","etag":null,"topics":["library"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"Dzinlife/Apple-Watch-Spring-Board","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gnikyt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-01-10T19:42:01.000Z","updated_at":"2024-07-02T09:14:12.000Z","dependencies_parsed_at":"2023-01-13T13:56:06.319Z","dependency_job_id":null,"html_url":"https://github.com/gnikyt/with","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fwith","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fwith/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fwith/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gnikyt%2Fwith/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gnikyt","download_url":"https://codeload.github.com/gnikyt/with/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245366205,"owners_count":20603438,"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":["library"],"created_at":"2024-10-29T09:16:14.996Z","updated_at":"2025-03-24T22:35:46.570Z","avatar_url":"https://github.com/gnikyt.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# With\n\nThis function simply mocks Python's [with statement](http://docs.python.org/release/2.5.3/ref/with.html) for PHP.\n\n![Tests](https://github.com/gnikyt/with/workflows/Package%20Test/badge.svg?branch=master)\n[![codecov](https://codecov.io/gh/gnikyt/with/branch/master/graph/badge.svg?token=qqUuLItqJj)](https://codecov.io/gh/gnikyt/with)\n[![License](https://poser.pugx.org/gnikyt/with/license)](https://packagist.org/packages/gnikyt/with)\n\n## Installation\n\nThe recommended way to install is [through composer](http://packagist.org).\n\n    composer require gnikyt/with\n\n## Usage\n\nThe with statement is used to wrap the execution of code with methods defined by a object. This allows common try...except...finally usage patterns to be encapsulated for convenient reuse.\n\nA with statement is defined as followed: `with([object], [callback]);`.\n\nThe executation of a with statement is done as followed:\n\n1. The `[object]`'s `__enter()` method is invoked\n2. The return value from `__enter()` is assigned to the first argument of the `[callback]`\n\u003e Note: The with statement guarantees that if the `__enter()` method returns without an error, then `__exit()` will always be called. Thus, if an error occurs during `__enter()`, it will be treated the same as an error occurring within the `[callback]` would be. See step 4 below\n3. The `[callback]` is executed\n4. The `[object]`'s `__exit()` method is invoked. If an exception caused the `[callback]` to be exited, the return value from `__enter()` and the `[callback]`'s exception are passed as arguments to `__exit()`. Otherwise, only the return value from `__enter()` is passed and the exception is set to null\n\u003e If the `[callback]` was exited due to an exception, and the return value from the `__exit()` method was false, the exception is rethrown. If the return value was true, the exception is suppressed, and execution continues with the statement following the with statement.\n\nHere is a sample object and a with-statement:\n\n```php\nclass Foo\n{\n    private $db;\n\n    //.. other code ..//\n\n    public function __enter()\n    {\n        $db = new PDO(\n                sprintf('%s:host=%s;dbname=%s', $this-\u003econfig['driver'], $this-\u003econfig['host'], $this-\u003econfig['db']),\n                $this-\u003econfig['user'],\n                $this-\u003econfig['pass']\n        );\n\n        $db-\u003esetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n\n        return $db;\n    }\n\n    public function __exit($db, $error = null)\n    {\n        if ($error instanceof Exception) {\n            $this-\u003elog('We had en error; Rolling back.');\n\n            $db-\u003erollback();\n        } else {\n            $this-\u003elog('Code ran fine. Committed.');\n\n            $db-\u003ecommit();\n        }\n\n        return true;\n    }\n}\n\n$foo = new Foo;\nGnikyt\\with($foo, function($db) {\n    $db-\u003ebeginTransaction();\n\n    $foo = 'osiset';\n    $sql = $db-\u003eprepare(\"INSERT INTO non_existant_table SET name = :foo\");\n    $sql-\u003ebindParam('foo', $foo, PDO::PARAM_STR);\n    $sql-\u003eexecute();\n});\n```\n\nYou're also free to implement the interface provided to ensure you're classes are compatible:\n\n```php\nuse Gnikyt\\Withable;\n\nclass Foo implements Withable\n{\n    // ...\n}\n```\n\nThe above example is processed as follows:\n\n+ `with` will call `$foo-\u003e__enter()`\n+ `$foo-\u003e__enter()` will setup the database, and return the PDO object\n+ `with` will now pass the PDO object to the callback as `$db` for use within the closure\n+ `with` now executes the callback closure\n+ The callback will throw an exception because the table does not exist\n+ `with` now calls `$foo-\u003e__exit()` and passed the `$db` object and the exception from the callback to it\n+ `$foo-\u003e__exit()` now checks for a exception and rollsback the changes. It returns `true` to suppress re-throwing the\nexception\n+ `with` now checks the return from `$foo-\u003e__exit()`, it sees it returns a `true` value, and does not re-throw the\nexception\n\n## Requirements\n\n- [PHP](http://php.net) \u003e= 8\n\n## Usage\n\nSee `examples/` for some basic usage code or this README.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnikyt%2Fwith","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgnikyt%2Fwith","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgnikyt%2Fwith/lists"}