{"id":15296450,"url":"https://github.com/phpmohamednabil/marrow-framework","last_synced_at":"2026-02-11T07:04:19.676Z","repository":{"id":194956386,"uuid":"692226717","full_name":"PHPMohamedNabil/marrow-framework","owner":"PHPMohamedNabil","description":"marrow is a php MVC Framework for building php web application with a good mvc pattern structure makes development more easier","archived":false,"fork":false,"pushed_at":"2024-06-20T09:38:00.000Z","size":122,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-15T19:35:46.699Z","etag":null,"topics":["mvc","mysql","oop","php","php-framework","php-library","php8"],"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/PHPMohamedNabil.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-15T21:21:47.000Z","updated_at":"2024-06-20T09:38:04.000Z","dependencies_parsed_at":"2024-09-30T18:10:39.007Z","dependency_job_id":"1add81e4-09e7-4e51-97cb-7cbca2d19929","html_url":"https://github.com/PHPMohamedNabil/marrow-framework","commit_stats":null,"previous_names":["phpmohamednabil/core-framework","phpmohamednabil/marrow-framework"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHPMohamedNabil%2Fmarrow-framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHPMohamedNabil%2Fmarrow-framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHPMohamedNabil%2Fmarrow-framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHPMohamedNabil%2Fmarrow-framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PHPMohamedNabil","download_url":"https://codeload.github.com/PHPMohamedNabil/marrow-framework/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248166937,"owners_count":21058481,"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":["mvc","mysql","oop","php","php-framework","php-library","php8"],"created_at":"2024-09-30T18:10:32.849Z","updated_at":"2026-02-11T07:04:19.617Z","avatar_url":"https://github.com/PHPMohamedNabil.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Marrow MVC architecture\n![marrow](https://github.com/PHPMohamedNabil/marrow-framework/assets/29188634/7bdc6061-86e4-4623-9f48-f6a2862e0256)\n\nA php framework Using  MVC design pattern build from zero with features like (command line micros,routes,template engine,containers,service provider pattern, mysql db,middlewares), help ypu understand poupler frameworks and how it works and operating from inside.\nget started with new project:\n\nsee the below repo to create new skeleton project.\nhttps://github.com/PHPMohamedNabil/marrow\n\n# **This the first version  and it is under testing**\n\nTable of contents\n=================\n\n\u003c!--ts--\u003e\n   * [Installation](#installation)\n   * [Request Lifecycle](#Request-lifecycle)\n      * [Kernal File](#kernal-file)\n      * [Kernal-from-inside](#Kernal-from-inside)\n      * [Routes](#Routes)\n      * [Style-template-engine](#Style-template-engine)\n      * [Middlewares](#Middlewares)\n      * [Controllers](#Controllers)\n      * [Models\u0026Database](#Models-Database)\n      * [creating-migration-file](#creating-migration-file)\n   * [Licence](#licence)\n\u003c!--te--\u003e\n\n# installation\n\n```php \ncomposer create-project php-mohamed-nabil/marrow --prefer-dist myapp\n```\n\n# Request-lifecycle\n\nall request to web applications directed to public/index.php file that acts as a front controller for all web application requests\n\n```php\n\u003c?php\n\ndefine('CoreStart',microtime());\n\nuse Core\\Request;\nuse Core\\Response;\nuse Core\\http\\Kernal;\n\nrequire('autoload.php');\n\n$app= require_once __DIR__.'/../bootstrap'.DS.'bootstrap.php';\n\n$kernal = new Kernal;\n\n$kernal-\u003elightOn();\n\n$kernal-\u003ehandle(new Request,$app);\n\n$kernal-\u003elightOff();\n\n```\nFirst thing is creating a application new instance and then run required classes or servicess (startups under startups folders) using kernal class\nto handel application request and then retrun response to the client.\n\n## kernal-file \n\nkernal file it is like a motherboard that conducts,configuraing and preparing all application settings and runs app services : \ncheck kenral file core/http/kernal.php:\n```php\n\u003c?php\n\nnamespace Core\\Http;\n\nuse Core\\Request;\nuse Optimus\\Onion\\Onion;\nuse Core\\App;\nuse Core\\Lightes\\LightesFaced;\nuse Core\\Lightes\\Lightes;\nuse Dotenv\\Dotenv;\nuse Core\\Session\\Storage\\SessionStorage;\nuse Core\\Session\\SessionFactory;\nuse Spatie\\Ignition\\Ignition;\nuse Core\\Configs\\Config;\n\nclass Kernal{\n\n\n    protected $app_middlewares=[];\n\n    public $lightes;\n\n    public function __construct()\n    {   \n       $dot_env = Dotenv::createMutable(ROOT_PATH);\n       $dot_env-\u003eload();\n         \n       app()::$config      = Config::getInstance();\n\n       app()-\u003esession      = SessionFactory::create(SessionStorage::class,require_once(SESSION_CONFIG));\n\n       $light_start        = new Lightes(require_once(CONFIG_CONSTAN.'startups.php'));\n        \n       $this-\u003elightes      = new LightesFaced($light_start);\n \n       app()-\u003e_csrftoken   = session_token();  \n\n          config()-\u003eload(CONFIG.DS.'app.php');\n    }\n\n```\n\n# lightes-component\n\n\nThis class implements design pattern you can choose or implement all services runs when application requests starts and run services after response returned:\ncheck core/lightes:\n\n**Applying on facade pattern**\n\n```php\n\u003c?php\n\nnamespace Core\\Lightes;\nuse Core\\Lightes\\LightesInterface;\n\n\nclass Lightes implements LightesInterface{\n     \n    private  $service_rooms;\n\n\tpublic function __construct(array $rooms)\n\t{\n        $this-\u003esetRoom($rooms);\n\t}\n\n\tpublic function setRoom($rooms)\n\t{\n\n           $this-\u003eservice_rooms=$rooms;\n\t}\n\n\tpublic function on()\n\t{ \n\t\t\n\t\tforeach($this-\u003eservice_rooms as $service)\n\t\t{\n\t\t\t   $service =  app()::$container-\u003eget($service);\n              \n\t\t\t   app()::$container-\u003eresloveClassMethod($service,'register');\n\t\t\t   app()::$container-\u003eresloveClassMethod($service,'startup');\n\t\t\t  \n\t\t}\n\n\t}\n\n\t\n\n\n\tpublic function off()\n\t{\n        \n\t}\n\n\n}\n```\nuse lightes interface for creating your own facede class implementation :\n```php\n\u003c?php\n\nnamespace Core\\Lightes;\n\n\ninterface LightesInterface{\n\n       public function on();\n\n       public function off();\n}\n```\n\n# Kernal-from-inside\n\nsee kernal handel function takes two parameters first is request object and seconde is application instance:\u003c/br\u003e\n\nruns middlewares before and afer application requests and then routes the request to the resource:\n```php\npublic function handle(Request $request,App $app)\n    {  \n        $onion =  new Onion;\n        \n        $onion-\u003elayer($this-\u003emiddlewares())-\u003epeel($request, function($request){\n                return $request;\n            });\n\n        return $app-\u003erun();\n    }\n```\n### kernal light on and light off methods:\nyou can see this methods runs every thing before request and after response outputed:\n\n```php\n\n    public function lightOn()\n    {  \n       $this-\u003eenviroment();\n       $this-\u003elightes-\u003eturnOn();\n       $this-\u003esetTimeZone();\n    }\n\n    public function lightOff()\n    {   \n        //after output services here\n         return $this-\u003elightes-\u003eturnOff();\n    }\n\n```\n\n\n## migration-commands\nto install db scheme run:\n``` php migrate ``` **run all migrations**\n``` php create_migration (migration_name) ``` **create new migration file in migration folder**\n``` php migrate role=(all)```  **rollback all migrations**\n``` php migrate role=(migration_name)``` **rollback migration_name file**\n\n## controllers and models commands\n\n``` php create_controller (controllername) ``` **create new controller file under controllers folder** \u003cbr /\u003e\n\n``` php create_controller (controlername) resource ```  **create new resource controller under controllers folder** \u003cbr /\u003e\n\n``` php create_controller (controlername) resource model ``` **create new resource controller and model file under controllers folder and model folder** \u003cbr /\u003e\n\n``` php create_controller (controlername) model ``` **create new controller and model file under controllers folder and model folder** \u003cbr /\u003e\n\n``` php create_model (modelname) ``` **create new model file under models folder** \u003cbr /\u003e\n\n``` php create_repo (repositoryname) ``` **create new respository file under respositories folder** \u003cbr /\u003e\n\n# env file\n\nyou can browse .env file to check and configure database connection and web app settings and session settings:\n\n```\nAPP_NAME=MyFIRSTAPP\nSECRET_KEY=4fe8895cff6b23cd1f49b1c14c34a5a161248d1fba2d55392d3ef7d3d6296811\nENVIROMENT=development\n\nDB=mysql\nHOSTNAME=localhost\nUSERNAME=root\nPASSWORD=\nDBNAME=native_api\n\nSESSION_LIFE_TIME=1800\nSESSION_IDLE_TIME=1000\n```\nfeal free to edit the above setting to your enviroment settings.\n\n## generate app secret key\nthis secert key important as it is important in hashing data algorithim it is hashes application name and uses it hashing process as secret key.\n\n**run command php generate_key** \n\n![generate key](https://github.com/PHPMohamedNabil/PHP-Navtive-JWT-API/assets/29188634/d0bfe349-d6a7-4030-977c-674f5f5b613f)\n\nyou will see key generated take it and copy it in  as a value of SECERET_KEY in .env file\n\n# Routes \n\n**Supporting GET,POST,HEAD,PUT,DELETE,OPTIONS**\n\nroutes located in app\\routes folder:\n1-web.php for web routes\n\nin our project we working on  routes you can change it as you want:\n\n```php\nuse App\\Core\\Route\\Router as Route;\nuse App\\Controllers\\ProductController;\nuse App\\Controllers\\UserController;\n\nRoute::get('/',function(){\n   return view('home');\n});\n\nRoute::middlewares('api',function(){\n    \n   Route::prefix('api/',function(){\n      \n      Route::resource(['product'=\u003eProductController::class]);\n\n      Route::post('/user/register',[UserController::class,'store']);\n      Route::get('/users/',[UserController::class,'allUsers'])-\u003emiddleware('checktoken');\n      Route::post('/user/login',[UserController::class,'userAuth']);\n\n      Route::get('/user/profile',[UserController::class,'profile'])-\u003emiddleware('checktoken');\n      \n   });\n\n\n\n});\n```\n## routes placeholders\ncreate route placeholders just but : before the placholder:\n```php\n\nuse App\\Core\\Route\\Router as Route;\nuse App\\Controllers\\ProductController;\nuse App\\Controllers\\UserController;\n\nRoute::get('/user/:id',[UserController::class,'profile']);\n```\n### routes regx route\nmake regex routes with method regx just write your own regular expressions (without regx delemeters):\n\n```php\n\nuse App\\Core\\Route\\Router as Route;\nuse App\\Controllers\\ProductController;\nuse App\\Controllers\\UserController;\n\nRoute::get('/user/:id',[UserController::class,'profile'])-\u003eregx('(\\d+)$');\n```\n## App routes list \nrun command ** php route_list** to see app routes\n\n![routelist](https://github.com/PHPMohamedNabil/PHP-Navtive-JWT-API/assets/29188634/5fd13226-1a22-4745-9a0d-12caddfee243)\n\n## Style-template-engine\nmarrow uses style template engine it is an fast and powerfull php template engine built from native code with strong featues like (template inheritance,template sections and hard compile feature)\nsee style documentation here :[style](https://github.com/PHPMohamedNabil/Style) \n\n## App url \nyour will go to app\\config\\config_constants.php file :\nyou will see all application constatnt the most imporatant part is SITE_URL\n\n```php\n//webiste address and routes\ndefine('ROUTES_WEB',APP.'routes');\ndefine('SITE_URL','http://localhost:8000/');\ndefine('SITE_AD_URL','http://localhost:8000/admin/');\ndefine('VENDOR',ROOT_PATH.'vendor'.DS);\n```\nchange SUTE_URL constant to your website or localhost url that has a document root in to public folder.\n\n# _tcsrf\nthis a csrf token parameter you have to send it along with any post request (check cookies to get the full csrf token ) see like that:\n\n# Middlewares \n\ncreate application general middlwares or routes middlewares from config/middlewares.php and disable remove csrf middleware from middlewares array.\n\n```php\n\u003c?php\nuse App\\Middlewares\\csrf;\nuse App\\Middlewares\\PostSize;\nuse App\\Middlewares\\test;\nuse App\\Middlewares\\XcsrfCookie;\nuse App\\Middlewares\\ViewValidationError;\nuse App\\Middlewares\\ApiMiddlware;\nuse App\\Middlewares\\isLogedIn;\n\nreturn[\n        //startup application middleware here\n      'web'=\u003e[\n               ViewValidationError::class,\n               csrf::class,\n               XcsrfCookie::class,\n           \n        ],\n        //routes middlewares here example: ['middleware_name'=\u003e'middleware']\n      'route'=\u003e[\n           'test'        =\u003e test::class,\n           'api'         =\u003e ApiMiddlware::class,\n           'checktoken'  =\u003e isLogedIn::class\n      ]\n];\n```\n\n# Service-providers\n\ncreate application service provider (classess and servicess runs before application bootstraped).\nthis classes you can create under startup folder and assign it to startups array in app\\config\\startup.php.\n\n**Applying on Container Pattern (Inversion of control)**\n\ngo to startup folder and create new file example : \nTimeZoneStartup.php for setting default timezone before app startsup (before every request to application)\n**like service providers in laravel framwork**\n\n```php\n\u003c?php\n\nnamespace App\\Startups;\n\nuse App\\Repositories\\BookInterface;\nuse App\\Repositories\\BookRepository;\nuse App\\Core\\Container\\Container;\nuse App\\Startups\\StartupInterface;\nuse App\\Core\\Database\\NativeDB;\nuse App\\Core\\Request;\nclass TimeZoneStartup implements StartupInterface\n{\n   //timezone service provider if you are saving timezone in db\n   //and wants to change it before application startup\n      \n      public function startup()\n      {  \n        config()-\u003eset('date_default_timezone_set','Europe/Moscow');\n\n        //example:'Europe/Moscow'     \n      }\n\n      public function register()\n      {   \n         \n      }\n\n      \n      \n}\n\n```\nThis means that every request to application will set date_default_timezone_set to 'Europe/Moscow' \nor you can write your other method to change timzone like date_default_timezone_set() builtin php function.\n\n**all startups are run one by one instantiating every class and run (boot) startup method then run register method**\n\n```php\n\u003c?php\n\n\nuse App\\Startups\\ProductStartup;\nuse App\\Startups\\TimeZoneStartup;\n\nreturn[\n\n     ProductStartup::class,\n     TimeZoneStartup::class\n\n];\n\n```\n# Controllers\n\nacting like controller system in laravel (emulate most)\nyou can assign middleware at constructor function:\n\n```php\n\u003c?php\n\nnamespace App\\Controllers;\n\nuse Core\\Controller;\nuse Style\\Style;\nuse Core\\Request;\n\nclass HomeController extends Controller\n{  \n\t  \n\n\t public function __construct()\n\t {\n\t \t//middleware_array,except_methods array(optional)\n        $this-\u003emiddleware(['test',['home']]);\n\t }\n\n```\n\n# Models-Database\n\njust create models like any framworks but it is uses native db (no ORM libaraies here).\n\n```php\n\n\u003c?php\n\nnamespace App\\Models;\n\nuse Core\\Model;\n\nclass UserModel extends Model\n{  \n\t//you have to set table attributes her $id,$column_2,$column_3 ...\n\t//you should set table name attribute or we can predict it like User to be users ,UserCategory user_categories\n    protected $mass = ['username','email']; // for mass assignment\n\t\n}\n\n```\nconnecting to database like this : \n\n**all models returns object of model data**\n\n```php\n             // $model = new user(12);\n\t\t//$model-\u003ecolumns['model_title']='updated';   \n\t\t//$model-\u003ecolumns['model_price']=2500000;  \n         \n       \n        //$model-\u003ecreate(['model_title'=\u003e'coding model']); //for mass assignment\n\t\t//$model-\u003esave(); //for insert\n\t\t//$model-\u003eamend();// for update\n\t\t//$model-\u003epurge(); //for delete\n\t\t//$model-\u003edeleteSoft(12); //for soft delete  \n\n```\nor like this :\n\n```php\n $user = new user;\n$user-\u003eget() // all users\n$user-\u003eget(12) //user with id = 12\n$user-\u003ecreate(['username'=\u003e'hambola','password'=\u003e123]); // create new user hambola with new password\n$user-\u003epurge(12); remove user number  12 with (id=12)\n$user-\u003eupdate($this-\u003emodel-\u003etable,['username'=\u003e'hmobla edited'],['id'=\u003e12]); edit user hambola with id =12\n```\n# NativeDB-class\nyou can create custom queries easy and fast using this class :\n\n```php\n\u003c?php\n\nnamespace App\\Repositories;\n\nuse App\\Repositories\\ProductRepositoryInterface;\nuse App\\Models\\Product;\nuse App\\Core\\Database\\NativeDB;\n```\n```php\n $users = NativeDB::getInstance()-\u003etable('users')-\u003epaginate(10); returns array first element is data object ,seconde is key 'links' which has pagination links\n $links = $users?$users['links']:[];\n\n             foreach($users[0] as $user)\n              {\n                 echo $user-\u003eusername.':'.$user-\u003eid;\n              }\n```\n```php\nNativeDB::getInstance()-\u003etable('users')-\u003eselect('username')-\u003elimit(10)-\u003erun();  //username from users table limi 10 records\nNativeDB::getInstance()-\u003etable('users')-\u003eselect('username')-\u003ewhere('id','=',12)-\u003erun(); //username from users table where id =12\nNativeDB::getInstance()-\u003etable('users')-\u003eselect('username')-\u003ewhere('id','=',12)-\u003ewhere('username','=','hambola')-\u003erun();   //username from users table where id =12 and username = hambola\nNativeDB::getInstance()-\u003etable('users')-\u003eselect('username')-\u003egroup_by('id')-\u003erun(); //username from users table groub by id\nNativeDB::getInstance()-\u003etable('users')-\u003einsertInto(['username'=\u003e'hambola brother'])-\u003erun(); //insert new user from users table\nNativeDB::getInstance()-\u003etable('users')-\u003edeleteRow(['username'=\u003e'hambola brother'])-\u003erun(); // delete where username hambola borhter\nNativeDB::getInstance()-\u003etable('users')-\u003eupdateRow(['username'=\u003e'hambola sister'],['id'=\u003e13],$whereoperator='',$soft_delete=false)-\u003erun(); // update  where id = 13 (keep two last params as example till further updates).\n```\n## creating-migration-file\nFirst **run command php create_migration users_table** (replace users_table by your migration file name ).\nit will create a new file users_table_date_time_000 under migration folder\n```php\n\u003c?php\n\nnamespace App\\Migrations;\n\nuse Core\\Database\\NativeDB;\n\nclass users__2023_09_03_17_56_59{\n      \n     //$db for database object\n\tpublic function up($db)\n\t{\n          $db-\u003equery('CREATE TABLE IF NOT EXISTS  `users` (\n                 `id` BIGINT NOT NULL AUTO_INCREMENT,\n                 `username` varchar(256) NOT NULL,\n                 `password` VARCHAR(255) NOT NULL ,\n                 `created` datetime NOT NULL,\n\t\t\t\t `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n\t\t\t\tPRIMARY KEY (`id`)\n\n             )');\n           \n\n\t}\n\n     public function down($db)\n     { \n\n       $db-\u003equery('DROP TABLE users');\n\n     }\n```\nafter making migration file with sql scheme run** php migrate** iw will run all migration files and commit it all.\nto rollback your migration run php migrate rollback your  migration run **php migrate roll=users__2023_09_03_17_56_59 **\nfor rollback all migration run **php migrate roll=all**\n\n# Exceptions:\nhas a special custom style using ignition libarary\n![core_exception](https://github.com/PHPMohamedNabil/Core-MVC-PHP/assets/29188634/7e2ef83e-c961-4a09-9744-c3f059b507ec)\n\n\nThe concept of large framworks (middlewares,pipeline,repositories,commands,migrations,containers,configs,template-engine)\n\nfinally run php marrow to start your project on localhost:8000 or ex: run php marrow (port number) php marrow 4500 \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpmohamednabil%2Fmarrow-framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphpmohamednabil%2Fmarrow-framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpmohamednabil%2Fmarrow-framework/lists"}