Fondamenta di un progetto

20 Mar 2020 | M.A.D.R.

Ecco qui, oggi vediamo come gettare le fondamenta di un nostro "personale" progetto.

Immagino che abbiate letto l'articolo precedente "Framework Si o No? Solo per programmatori?" per capire bene il concetto.

Abbiamo visto l'approccio oggi iniziamo con l'utilizzo di librerie terze per le fondamenta, partiamo con l'occorrente:

  • Composer

Si serve solo composer per iniziare... Vediamo la struttura del nostro file composer.json (da aggiungere alla root della nostra applicazione).

"require": {
        "catfan/medoo": "^1.7",
        "smarty/smarty": "~3.1",
        "bramus/router": "~1.4",
        "symfony/psr-http-message-bridge": "^2.0",
        "nyholm/psr7": "^1.2"
    }

In ordine:

Nel dettaglio router come anticipato dall'articolo precedente sarà il cuore pulsante della nostra applicazione, mentre PSR sono le request che arriveranno al nostro server...

Non mi dilungherò ad inutili tecnicismi, vediamo la sostanza...

Dopo aver creato il file composer.json dovremo lanciare un comando da CLI (linea di comando)

compose install

Ed è tutto qui, abbiamo la base per la costruzione del nostro framework...

Vediamo come strutturare la nostra applicazione in modo logico ed evitando di utilizzare semplici file ".php" per gestire le richieste (è un modo antico-arcaico e soprattutto poco funzionale per la gestione delle richieste).

Logicamente la struttura potrebbe essere la seguente:

  • app
    • controller
    • model
  • helpers
  • libraries
  • public
    • theme
    • template
  • vendor

La directory APP conterrà "SOLO" la logica di operazione sui dati e consentirà l'accesso ai metodi per la gestione delle richieste.

Helpers conterrà "SOLO" file con funzioni custom che potranno essere richiamate in qualsiasi punto della nostra applicazione.

Libraries includerà "SOLO" Librerie esterne e/o Librerie scritte da noi

Public ... che dire... penso sia abbastanza semplice da intuire....

Vendor è la directory che ha creato composer per la gestione delle dipendenze.

A questo punto dobbiamo creare alcuni file che consentiranno l'utilizzo della nostra applicazione

File "index.php"

include_once __DIR__.'/vendor/autoload.php';
include_once __DIR__.'/helpers/index.php';
include_once __DIR__.'/loader.php';
include_once __DIR__.'/router.php';

File "loader.php"

$boot=[
	'MYROOT'=>__DIR__,
	'DIRECTORY_SEPARATOR'=>'/',
	'STORAGE'=>env('APP_BASE_DISK'),
];
array_walk($boot,function($v,$k){
	(!defined($k))?define($k,$v):null;
});
include_once MYROOT.'/app/Model.php';

autoloader(MYROOT.'/Libraries');
autoloader(MYROOT.'/'.env('APP_TRAITS'));
autoloader(MYROOT.'/'.env('APP_MODELS'));
autoloader(MYROOT.'/'.env('APP_CONTROLLERS'));
autoloader(MYROOT.'/'.env('APP_SERVICES'));

La funzione autoloader è implementata all'interno di index.php della directory helper che viene riportata di seguito

function env($key){
	return parse_ini_file('.env')[$key]??null;
}
function autoloader($path){
	foreach (scandir($path) as $file){
		($file!=='' && !in_array($file,['.','..']))?include_once $path.'/'.$file:null;
	}
}

File "router.php"

$router = new \Bramus\Router\Router();
$request=\Symfony\Component\HttpFoundation\Request::createFromGlobals();
$router->get('/',function(){
	echo 'sono la tua prima pagina'
});

Vediamo il core Model che si troverà all'interno della directory app (Model.php)

namespace App;

use Libraries\CompileData;
use Medoo\Medoo;
abstract class Model extends Medoo {

	protected $table='';
	public $conn;
	public $schema;
	protected
		$query,
		$where,
		$select,
		$operation,
		$fields_update,
		$join,
		$casts=[];

	public function __construct() {
		parent::__construct(
			[
				'database_type' => env('DB_ADAPTER'),
				'database_name' => env('DB_DBNAME'),
				'server' => env('DB_HOST'),
				'username' => env('DB_USER'),
				'password' => env('DB_PASS'),
				'logging'=>env('DB_LOCAL_LOG')
			]
		);
		
	}
	public function where($where=[]){
		$this->where=$where;
		return $this;
	}
	public function select( $table=null, $join = null, $columns = null, $where = null ) {
		(null===$table)?$table=$this->table:null;
		(!empty($this->where) && null===$where)?$where=$this->where:null;
		(!empty($this->join) && empty($join))?$join=$this->join:null;
		(empty($columns) && empty($join))?$join='*':$columns='*';
		return  $this->conn->select( $table, $join, $columns, $where ); // TODO: Change the autogenerated stub
	}
	public function _get( $where = null,$table=null,  $columns = null ) {
		(null===$table)?$table=$this->table:null;
		(!empty($this->where) && null===$where)?$where=$this->where:null;
		(empty($columns)  )?$columns='*':null;
		return $this->conn->get( $table,  $columns, $where ); // TODO: Change the autogenerated stub
	}
	public function insert( $datas,$table=null ) {
		(null===$table)?$table=$this->table:null;
		$data=CompileData::mappingData($this,$table,$datas,$this->casts);
		return $this->conn->insert( $table, $data ); // TODO: Change the autogenerated stub
	}
	public function update(  $data,$table=null, $where = null ) {
		(null===$table)?$table=$this->table:null;
		(!empty($this->where) && null===$where)?$where=$this->where:null;
		$data=CompileData::mappingData($this,$table,$data,$this->casts);
		return $this->conn->update( $table, $data, $where ); // TODO: Change the autogenerated stub
	}
	public function delete( $table=null, $where=null ) {
		(null===$table)?$table=$this->table:null;
		(!empty($this->where) && null===$where)?$where=$this->where:null;
		return $this->conn->delete( $table, $where ); // TODO: Change the autogenerated stub
	}
}

Questo è il cuore dei dati sul nostro DB.

Buon lavoro a tutti e soprattutto a breve l'implementazione completa.

Soluzioni complete per ogni esigenza