Domanda

Sto lavorando al progetto dedicato in uscita scritto in CakePhp, che è diventato piuttosto grande. L'architettura utilizza anche un sacco di plugin. Dall'inizio del progetto c'era solo un'istanza di questa applicazione. Tuttavia, il cliente ha trovato un'altra area che l'applicazione può funzionare. Utilizzerà la stessa base di codice ma un database separato. Il fatto è che Codebase è effettivamente applicabile in circa il 90%, cosa significa che nella maggior parte delle volte farà il suo lavoro, ma ci sono alcune lievi cambiamenti necessari. Dopo alcuni piccoli miglioramenti è chiaro che tali modifiche continueranno per questa nuova istanza. Ma allo stesso tempo ci saranno cambiamenti applicabili per entrambe le istanze. Non sarebbe una soluzione molto pulita per fare un sacco di condizioni in tutta l'applicazione e verificare quale istanza sia effettivamente in esecuzione.

Quindi la mia idea è:

  • Conservare il progetto in un repository e apportare modifiche e correzioni applicabili per tutte le istanze in una base di codice
  • Crea una sorta di "mod" che conterrà classi che sovraccaricheranno le classi predefinite del progetto solo quando necessario e solo per l'istanza specifica
  • Per renderlo più chiaro, sarebbe meglio avere una struttura di file parallela alla directory dell'app che conterrà quelle nuove classi (ovviamente solo quelle necessarie)
  • La cosa molto importante è non toccare affatto il nucleo della torta, voglio essere in grado di aggiornarlo in qualsiasi momento senza problemi

Esempio:

app/controllers/invoices_controller.php:
InvoicesController extends AppController {
  public function generateInvoice() {}
}

newbusinness/controllers/invoices_controller.php:
NewbusinessInvoicesController extends InvoicesController {
  public function generateInvoice() {}
}

Cosa è importante quando andremo a:

www.mynewbusinnes.com/Invoices/generateInvoice

Il sistema chiamerà automaticamente NewbusinessInvoicesController->generateInvoice(), perché esistono tale controller e metodo. Altrimenti chiamerebbe controller e metodi predefiniti.

Quindi è possibile creare tale modalità per CakePHP, forse a basso livello di classi di caricamento? Non vorrei usare runkit_method_redefine() e sostituire ad esempio il App::import() metodo, finché runkit_method_redefine() è contrassegnato come "sperimentale". Qualche suggerimento o idee?

È stato utile?

Soluzione

Quindi è possibile creare tale modalità per CakePHP, forse a basso livello di classi di caricamento? Non vorrei usare runkit_method_redefine () e sostituire ad esempio il metodo App :: import (), purché runKit_method_redefine () sia contrassegnato come "sperimentale". Qualche suggerimento o idee?

Tutte le richieste inizialmente passano app/webroot/index.php. Questo file non fa parte del core e può essere modificato da te. Quello che puoi fare è cambiare il includere percorsi Per elencare una cartella della tua stessa creazione prima CAKE_CORE_INCLUDE_PATH. Qui ho impostato /absolute/path/to/custom Come percorso include:

if (function_exists('ini_set') && ini_set('include_path', ROOT . DS . 'custom' . PATH_SEPARATOR . CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) {

A seguito di questa sezione, viene caricato il file bootstrap principale di CakePhp (/cake/bootstrap.php) e molte classi di base iniziano a essere caricate:

require CORE_PATH . 'cake' . DS . 'basics.php';
$TIME_START = getMicrotime();
require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php';
require LIBS . 'object.php';
require LIBS . 'inflector.php';
require LIBS . 'configure.php';
require LIBS . 'set.php';
require LIBS . 'cache.php';
Configure::getInstance();
require CAKE . 'dispatcher.php';

Dopo aver inserito il tuo percorso include, puoi sostituirli copiandoli su quel percorso:

ROOT
|- app/
|- cake/
  |- libs/
    |- configure.php // this would usually be loaded
|- custom/
  |- cake/
    |- libs/
      |- configure.php // now this is loaded

(Notare la configure.php Il file contiene entrambi i Configure e App classi.)

In breve, cambiando una singola riga in app/webroot/index.php, ora puoi sostituire qualsiasi parte del core di CakePhp senza modificarlo direttamente.

Ora potresti essere in grado di apportare le modifiche richieste a App::import Ma, poiché questo non è effettivamente documentato da nessuna parte, il tuo chilometraggio può variare.

Altri suggerimenti

Quindi la mia idea è:

  • Conservare il progetto in un repository e apportare modifiche e correzioni applicabili per tutte le istanze in una base di codice
  • Crea una sorta di "mod" che conterrà classi che sovraccaricheranno le classi predefinite del progetto solo quando necessario e solo per l'istanza specifica
  • Per renderlo più chiaro, sarebbe meglio avere una struttura di file parallela alla directory dell'app che conterrà quelle nuove classi (ovviamente solo quelle necessarie) - molto importante è non toccare affatto il nucleo della torta, voglio essere in grado di aggiornarlo in qualsiasi momento senza problemi

L'ho toccato in un Risposta precedente, ma Percorsi di classe aggiuntivi Sembra che potrebbe essere la funzione CakePHP che stai cercando. Qualcosa come il seguente app "mod" bootstap.php dovrebbe dire a CakePhp di caricare anche i file da a core Directory:

App::build(array(
    'plugins'     => array(ROOT . DS . 'core' . DS . 'plugins' . DS),
    'models'      => array(ROOT . DS . 'core' . DS . 'models' . DS),
    'views'       => array(ROOT . DS . 'core' . DS . 'views' . DS),
    'controllers' => array(ROOT . DS . 'core' . DS . 'controllers' . DS),
    'datasources' => array(ROOT . DS . 'core' . DS . 'models' . DS . 'datasources' . DS),
    'behaviors'   => array(ROOT . DS . 'core' . DS . 'models' . DS . 'behaviors' . DS),
    'components'  => array(ROOT . DS . 'core' . DS . 'controllers' . DS . 'components' . DS),
    'helpers'     => array(ROOT . DS . 'core' . DS . 'views' . DS . 'helpers' . DS),
    'vendors'     => array(ROOT . DS . 'core' . DS . 'vendors' . DS),
    'shells'      => array(ROOT . DS . 'core' . DS . 'vendors' . DS . 'shells' . DS),
    'locales'     => array(ROOT . DS . 'core' . DS . 'locale' . DS),
));

Quanto sopra assume una nuova struttura di cartelle che, anziché /app e /cake, Somiglia a questo:

- ROOT
|- app1 // look here first,
|- app2
|- core // then here,
|- cake // then lastly here.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top