1. Interfejsy, przyklad rzeczywisty z mojego FW
<?php
class Framework_Session_SessionManager
{
/**
* @var Framework_Session_SessionStorage $sessionStorage
*/
private $sessionStorage;
public function __construct( Framework_Session_SessionStorage $sessionStorage )
{
$this->sessionStorage = $sessionStorage;
}
/**
* @param string $sid session id
* @return Framework_Session_Session
*/
public function initializeSession( $sid = null )
{
{
$sid = $this->generateNewSID();
}
{
$sid = $this->generateNewSID();
}
return $this->sessionStorage->loadSession( $sid );
}
/**
* @param Framework_Session_Session $session
* @return boolean whether was successfull
*/
public function finalizeSession( Framework_Session_Session $session )
{
return $this->sessionStorage->storeSession($session);
}
/**
* @return string new SID
*/
private function generateNewSID()
{
}
}
?>
Framework_Session_SessionStorage zajmuje sie zapisem i odczytem obiektu sesji, jako ze nie potrzebuje zaimplementowac tutaj
zadnej metody to wystarcza mi intefrejs
<?php
interface Framework_Session_SessionStorage
{
/**
* Stores session object
* @param $session
* @return boolean
*/
public function storeSession( Framework_Session_Session $session );
/**
* Loads session object
* @param string $id ID of the session
* @return Framework_Session_Session
*/
public function loadSession( $id );
/**
* Removed session identified by $id
*/
public function removeSession( $id );
}
?>
pierwsza implementacja interfejsu
<?php
class Framework_Session_FileSessionStorage implements Framework_Session_SessionStorage
{
private $sessionsDir;
public function __construct( $sessionsDir )
{
$this->sessionsDir = $sessionsDir;
}
public function storeSession( Framework_Session_Session $session )
{
$id = $session->getID();
$filename = $this->buildFilename( $id );
$serializedData = serialize( $session->getAllData() ); file_put_contents( $filename, $serializedData );
return true;
}
/**
* @param integer $id Session id
* @return Framework_Session_Session
*/
public function loadSession( $id )
{
$filename = $this->buildFilename( $id );
{
return new Framework_Session_Session( $id );
}
if ( $serializedData === FALSE )
{
return new Framework_Session_Session( $id );
}
if ( $data === FALSE )
{
return new Framework_Session_Session( $id );
}
$session = Framework_Session_SessionnewInstance( $id, $data );
return $session;
}
public function removeSession( $id )
{
$filename = $this->buildFilename( $id );
{
return true;
}
}
private function buildFilename( $id )
{
$filename = $this->sessionsDir . "/sess_" . $id;
return $filename;
}
}
?>
druga implementacja interfejsu
<?php
class Framework_Session_PDOSessionStorage implements Framework_Session_SessionStorage
{
/**
* @var PDO
*/
private $pdo = null;
private $tableName = "core_session";
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function setTableName($tableName = "core_session")
{
$this->tableName = $tableName;
}
/**
* Stores session object
* @param $session
* @return boolean
*/
public function storeSession( Framework_Session_Session $session )
{
try
{
$sql = "SELECT COUNT( id ) AS the_count FROM " . $this->tableName . " WHERE session_id = ?";
$statement = $this->createStatement($sql, array( $session->getID())); $statement->execute();
$count = $statement->fetchColumn(0);
$statement->closeCursor();
$sessionExists = ($count == 1); // 0 or 1 [unique session id]
if ( $sessionExists )
{
// update
$sql = "UPDATE " . $this->tableName . " SET updated_at = ?, data = ? WHERE session_id = ?";
$statement = $this->createStatement($sql, $values);
$statement->execute();
}
else
{
// insert
$sql = "INSERT INTO " . $this->tableName . " ( session_id, created_at, updated_at, data ) VALUES ( ?, ?, ?, ? )";
$statement = $this->createStatement($sql, $values);
$statement->execute();
}
return true;
}
catch ( PDOException $e )
{
return false;
}
}
/**
* Loads session object
* @param string $id ID of the session
* @return Framework_Session_Session
*/
public function loadSession( $id )
{
try
{
$sql = "SELECT * FROM " . $this->tableName . " WHERE session_id = ?";
$statement = $this->createStatement($sql, array( $id )); $statement->execute();
$row = $statement->fetch(PDOFETCH_ASSOC);
if ( ! $row )
{
return Framework_Session_SessionnewInstance($id);
}
else
{
$data = unserialize_utf8($row['data']);
return Framework_Session_SessionnewInstance($id, $data);
}
}
catch ( PDOException $e )
{
// session does not exist, create new one
return Framework_Session_SessionnewInstance($id);
}
}
/**
* Removed session identified by $id
*/
public function removeSession( $id )
{
try
{
kill(); // XXX
$sql = "DELETE FROM " . $this->tableName . " WHERE session_id = ?";
$statement = $this->createStatement($sql, $values);
$statement->execute();
return true;
}
catch ( PDOException $e )
{
return false;
}
}
/**
* @param string $sql
* @param array $values
* @return PDOStatement
*/
private function createStatement
($sql, $values = array()) {
$statement = $this->pdo->prepare($sql);
$i = 0;
foreach ( $values as $value )
{
$statement->bindParam( $i + 1, $values[$i] ); // DONT use value!!! as all fields have save value
$i++;
}
return $statement;
}
}
?>
<?php
// przekazuje managerowi jakis obiekt klasy ktora implementuje interfejs Framework_Session_SessionStorage.
// menadzera nie interesuje jaki to obiekt, ma tylko implementowac odpowiedni interfejs, czyli posiadac odpowiednie metody
$sessionManager = new Framework_Session_SessionManager( new Framework_Session_FileSessionStorage( '/tmp/sessions' ) );
?>
Ten twoj kod ostatni - skasuj i nie patrz na niego wiecej, to cos strasznego, nie ma zadnego sensu, jest bledne itd.
Wybacz ze nie tlumacze czemu - ale po prostu caly kod jest bez sensu, chociaz sie kompiluje.
Co do metod statycznych:
Mam metody fabryczne (http://en.wikipedia.org/wiki/Factory_method_pattern )
public static function initWithEmailTemplateName($emailTemplateName){...}
public static function initWithEmailTemplate(EmailTemplate $emailTemplate){...}
sluzace do utworzenia nowego obiektu w rozny sposob, albo podajac obiekt, albo nazwe wg ktorej znajde sobie ten obiekt.
Do tego mam prywatny konstruktor, zeby po prostu go nie uzywac, tylko wlasnie tych metod.
Mozna by zrobic rozpoznawanie przekazanego parametru do konstruktora i robic to samo w konstruktorze, ale
nie pamietamy jakie parametry konstruktor przyjmuje, wlaczamy podpowiadanie i widzimy __construct( $emailTemplate )
i co mozemy tam wrzucic? e? musimy zajrzec do kodu, ew. przeczytac wiecej dokumentacji zeby sie dowiedziec ze
ten parametr moze przyjmowac obiekt albo stringa.
Co innego w np Javie, mozesz miec 2 konstruktory, jeden przyjmuje Stringa drugi EmailTemplate.
A moje metody same mi mowia jaki parametr mam podac, czy to string czy obiekt.
<?php
class Application_Email_SystemEmailSender
{
private $senderName = '';
private $senderEmail = '';
/**
* @var EmailTemplate
*/
private $emailTemplate = null;
private static $alreadyInitialized = false; /**
* Data for filling the template
* @var array
*/
private function __construct(EmailTemplate $emailTemplate)
{
$this->emailTemplate = $emailTemplate;
$this->initSettings();
}
/**
* Loads deafult sender data
*
*/
private function initSettings()
{
if ( self$alreadyInitialized )
{
return;
}
$this->senderEmail = SystemSettinggetByName('email', 'sender_email')->getData();
$this->senderName = SystemSettinggetByName('email', 'sender_name')->getData();
self$alreadyInitialized = true;
}
/**
* Changes default sender data
*
* @param string $name
* @param string $email
*/
public function setSender($name, $email)
{
$this->senderName = $name;
$this->senderEmail = $email;
}
/**
* @param string $templateName
* @return Application_Email_SystemEmailSender
*/
public static function initWithEmailTemplateName
($emailTemplateName) {
try
{
$emailTemplateSearch = new EmailTemplateSearch();
$emailTemplate = $emailTemplateSearch->findOneByName( $emailTemplateName );
$ses = new self($emailTemplate);
return $ses;
}
catch (DAO_RecordNotFoundException $e )
{
throw new Application_SystemEmailSenderException($e);
}
}
/**
* @param EmailTemplate $emailTemplate
* @return Application_Email_SystemEmailSender
*/
public static function initWithEmailTemplate
(EmailTemplate
$emailTemplate) {
$ses = new self($emailTemplate);
return $ses;
}
/**
* @param array $data
*/
public function setData($data)
{
$this->data = $data;
}
/**
* Sends email to User with previously set data
*
* @param User $user
*/
public function sendEmailToUser(User $user)
{
// add user to data
$subject = $this->emailTemplate->subject;
$body = $this->emailTemplate->getFilledBody($data);
$senderName = $this->senderName;
$senderEmail = $this->senderEmail;
$recipientEmail = $user->email;
$recipientName = $user->getFullName();
$emailSender = new Framework_Libs_Email_SimpleEmailSender();
$emailSender->sendHTMLEmail($senderName, $senderEmail, $recipientName, $recipientEmail, $subject, $body );
}
}
?>
Albo prosta klasa z prostymi uzytkowymi funkcjami, mozna by to tez niestatycznie zrobic, ale po co, potem bedziesz mial wiecej pisania:
<?php
$au = new AppUtils()
$au->randomString( 5 );
?>
<?php
class AppUtils
{
public static function randomString
($length) {
return join( "", $randomChars ); }
}
?>
Albo niesmierterlny singleton
<?php
class Framework_Language_LanguageManager
{
private static $instance = null; /**
* @return Framework_Language_LanguageManager
*/
public static function getInstance
() {
{
self$instance = new self();
}
return self$instance;
}
private function __construct()
{
$this->languageLoader = new Framework_Language_LanguageLoader();
$this->loadAllLanguages();
}
// ...
}
?>
Wlasciwie to w wiekszosci te 3 typy statycznych metod mi wystarczyly.