homepage:
url: /
param: { module: question, action: list }
czwartek, 11 września 2008
Symfony krok 5
W pliku /apps/frontend/config/routing.yml można ustawić która strona zostaje wyświetlona jako "index" naszej aplikacji:
wtorek, 9 września 2008
Symfony user managmet and sessions
Sesje użytkowników są przechowywane w symfony w obiekcie User. Możemy pobrać ten obiekt w dowolnym miejscu za pomocą metody getUser();
Oczywiście w tym obiekcie możemy przechowywać obiekty (niezalecane) i zmienne które będą dostępne pomiędzy wywołaniami stron.
Zmienne możemy ustawiać, pobierać i czyścić
Do sesji użytkownika możemy dobrać się także z szablonów
Jeśli potrzebujemy przechować informację tylko do kolejnego wywołania, np potwierdzenie zapisania/usunięcia/edycji danych możemy skorzystać z metody setFlash i getFlash. Dane zapisane za pomocą tych metod zostaną usunięte przy kolejnym wywołaniu.
np.
Ciasteczka
W symfony możemy decydować gdzie zapisane są ciasteczka. Określamy to w pliku apps/myapp/config/factories.yml
Po stronie aplikacji sesje są przechowywane domyślnie w plikach. Możemy to zmienić w pliku apps/myapp/config/factories.yml
Czas przechowywania sesji można ustawić w pliku apps/myapp/config/settings.yml
class mymoduleActions extends sfActions
{
public function executeFirstPage()
{
$nickname = $this->getRequestParameter('nickname');
// Store data in the user session
$this->getUser()->setAttribute('nickname', $nickname);
}
public function executeSecondPage()
{
// Retrieve data from the user session with a default value
$nickname = $this->getUser()->getAttribute('nickname', 'Anonymous Coward');
}
}
Oczywiście w tym obiekcie możemy przechowywać obiekty (niezalecane) i zmienne które będą dostępne pomiędzy wywołaniami stron.
Zmienne możemy ustawiać, pobierać i czyścić
class mymoduleActions extends sfActions
{
public function executeRemoveNickname()
{
$this->getUser()->getAttributeHolder()->remove('nickname');
}
public function executeCleanup()
{
$this->getUser()->getAttributeHolder()->clear();
}
}
Do sesji użytkownika możemy dobrać się także z szablonów
Hello, getAttribute('nickname') ?>
Jeśli potrzebujemy przechować informację tylko do kolejnego wywołania, np potwierdzenie zapisania/usunięcia/edycji danych możemy skorzystać z metody setFlash i getFlash. Dane zapisane za pomocą tych metod zostaną usunięte przy kolejnym wywołaniu.
np.
$this->setFlash('attrib', $value);
$value = $this->getFlash('attrib');
// i w szablonach
has('attrib')): ?>
get('attrib') ?>
Ciasteczka
W symfony możemy decydować gdzie zapisane są ciasteczka. Określamy to w pliku apps/myapp/config/factories.yml
all:
storage:
class: sfSessionStorage
param:
session_name: my_cookie_name
Po stronie aplikacji sesje są przechowywane domyślnie w plikach. Możemy to zmienić w pliku apps/myapp/config/factories.yml
all:
storage:
class: sfMySQLSessionStorage
param:
db_table: SESSION_TABLE_NAME # Name of the table storing the sessions
database: DATABASE_CONNECTION # Name of the database connection to use
Czas przechowywania sesji można ustawić w pliku apps/myapp/config/settings.yml
default:
.settings:
timeout: 1800 # Session lifetime in seconds
Symfony krok 4
W niektórych przypadkach potrzebujemy tylko wysłać nagłówek:
lub wybrać szablon o dowolnej nazwie
Przydatnymi metodami są także forward, redirect i forward404 (nie można znaleźć strony. Dzięki nim możemy przejść do innej akcji w innym module lub załadować dowolną stronę.
Jeśli mamy czynność którą musimy powtórzyć przed / po wykonaniu każdej akcji możemy utworzyć metody preExecute() i postExecute()
Funkcje pomocne przy wykonywaniu akcji:
Przykłady wykorzystania:
pobieranie parametrów:
upload plików:
public function executeRefresh()
{
$output = '<"title","My basic letter"],["name","Mr Brown">';
$this->getResponse()->setHttpHeader("X-JSON", '('.$output.')');
return sfView::HEADER_ONLY;
}
lub wybrać szablon o dowolnej nazwie
$this->setTemplate('myCustomTemplate');
Przydatnymi metodami są także forward, redirect i forward404 (nie można znaleźć strony. Dzięki nim możemy przejść do innej akcji w innym module lub załadować dowolną stronę.
$this->forward('otherModule', 'index');
$this->redirect('otherModule/index');
$this->redirect('http://www.google.com/');
/**
* szablon do strony 404 znajduje się w $sf_symfony_data_dir/modules/default/
* możemy także nadpisać akcje error404 w dowolnym module, oraz dołączyć do modułu
*/
forward404();
/**
* istnieje tez kilka funkcji pomocniczych które ułatwią nam pracę
*/
forwardIf();
forwardUnless();
forward404If();
forward404Unless();
redirectIf();
redirectUnless();
$this->forward404If(!$article);
Jeśli mamy czynność którą musimy powtórzyć przed / po wykonaniu każdej akcji możemy utworzyć metody preExecute() i postExecute()
public function preExecute()
{
// The code inserted here is executed at the beginning of each action call
...
}
public function executeIndex()
{
...
}
public function executeList()
{
...
$this->myCustomMethod(); // Methods of the action class are accessible
}
public function postExecute()
{
// The code inserted here is executed at the end of each action call
...
}
Funkcje pomocne przy wykonywaniu akcji:
Name Function Sample Output
Request Information
getMethod() Request method Returns sfRequest::GET or sfRequest::POST constants
getMethodName() Request method name 'POST'
getHttpHeader('Server') Value of a given HTTP header 'Apache/2.0.59 (Unix) DAV/2 PHP/5.1.6'
getCookie('foo') Value of a named cookie 'bar'
isXmlHttpRequest()* Is it an Ajax request? true
isSecure() Is it an SSL request? true
Request Parameters
hasParameter('foo') Is a parameter present in the request? true
getParameter('foo') Value of a named parameter 'bar'
getParameterHolder()->getAll() Array of all request parameters
URI-Related Information
getUri() Full URI 'http://localhost/myapp_dev.php/mymodule/myaction'
getPathInfo() Path info '/mymodule/myaction'
getReferer()** Referrer 'http://localhost/myapp_dev.php/'
getHost() Host name 'localhost'
getScriptName() Front controller path and name 'myapp_dev.php'
Client Browser Information
getLanguages() Array of accepted languages Array( [0] => fr [1] => fr_FR [2] => en_US [3] => en )
getCharsets() Array of accepted charsets Array( [0] => ISO-8859-1 [1] => UTF-8 [2] => * )
getAcceptableContentTypes() Array of accepted content types Array( [0] => text/xml [1] => text/html
Przykłady wykorzystania:
pobieranie parametrów:
class mymoduleActions extends sfActions
{
public function executeIndex()
{
$hasFoo = $this->getRequest()->hasParameter('foo');
$hasFoo = $this->hasRequestParameter('foo'); // Shorter version
$foo = $this->getRequest()->getParameter('foo');
$foo = $this->getRequestParameter('foo'); // Shorter version
}
}
upload plików:
class mymoduleActions extends sfActions
{
public function executeUpload()
{
if ($this->getRequest()->hasFiles())
{
foreach ($this->getRequest()->getFileNames() as $uploadedFile)
{
$fileName = $this->getRequest()->getFileName($uploadedFile);
$fileSize = $this->getRequest()->getFileSize($uploadedFile);
$fileType = $this->getRequest()->getFileType($uploadedFile);
$fileError = $this->getRequest()->hasFileError($uploadedFile);
$uploadDir = sfConfig::get('sf_upload_dir');
$this->getRequest()->moveFile($uploadedFile, $uploadDir.'/'.$fileName);
}
}
}
}
niedziela, 7 września 2008
Symfony krok 3
Uruchomienie kodu symfony z lini poleceń:
Front controller to coś co przyjmuje zapytania i interpretuje je. Można dodać nowy kontroler, ale mnie interesują tylko dwa kontrolery, które już są zdefiniowane. Mianowicie:
Nazewnictwo klas akcji
Nazwa klasy musi zaczynać się od nazwy modułu z małej litery i kończyć się na Actions. Klasa musi być umieszczona w katalogu pps/myapp/modules/mymodule/actions/ a plik musi nazywać się actions.class.php
Każda metoda przynosząca nowe akcje musi zaczynać się od execute, a cała klasa musi dziedziczyć po sfActions.
Nazwa wywołania url jest wzięta z nazwy funkcji w ten sposób że jeśli utworzymy funkcję executeList poprawnym url dla tej akcji jest
lub
Możemy również tworzyć całe klasy dla poszczególnych akcji. Wtedy musimy dziedziczyć z klasy sfAction i tworzyć klasy o nazwie NazwaAkcjiAction.
np.
myapp/modules/mymodule/actions/indexAction.class.php
myapp/modules/mymodule/actions/listAction.class.php
Pobieranie informacji o wywołaniu:
Templates
Jeśli akcję zakończymy
Można też:
i
lub
define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..'));
define('SF_APP', 'myapp');
define('SF_ENVIRONMENT', 'prod');
define('SF_DEBUG', false);
require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
// add code here
Front controller to coś co przyjmuje zapytania i interpretuje je. Można dodać nowy kontroler, ale mnie interesują tylko dwa kontrolery, które już są zdefiniowane. Mianowicie:
http://localhost/index.php/mymodule/index
http://localhost/mymodule/index
i
http://localhost/myapp_dev.php/mymodule/index
Nazewnictwo klas akcji
Nazwa klasy musi zaczynać się od nazwy modułu z małej litery i kończyć się na Actions. Klasa musi być umieszczona w katalogu pps/myapp/modules/mymodule/actions/ a plik musi nazywać się actions.class.php
Każda metoda przynosząca nowe akcje musi zaczynać się od execute, a cała klasa musi dziedziczyć po sfActions.
class mymoduleActions extends sfActions
{
public function executeIndex()
{
}
}
Nazwa wywołania url jest wzięta z nazwy funkcji w ten sposób że jeśli utworzymy funkcję executeList poprawnym url dla tej akcji jest
http://localhost/myapp_dev.php/mymodule/list
lub
http://localhost/mymodule/list
Możemy również tworzyć całe klasy dla poszczególnych akcji. Wtedy musimy dziedziczyć z klasy sfAction i tworzyć klasy o nazwie NazwaAkcjiAction.
np.
myapp/modules/mymodule/actions/indexAction.class.php
class indexAction extends sfAction
{
public function execute()
{
...
}
}
myapp/modules/mymodule/actions/listAction.class.php
class listAction extends sfAction
{
public function execute()
{
...
}
}
Pobieranie informacji o wywołaniu:
class mymoduleActions extends sfActions
{
public function executeIndex()
{
// Retrieving request parameters
$password = $this->getRequestParameter('password');
// Retrieving controller information
$moduleName = $this->getModuleName();
$actionName = $this->getActionName();
// Retrieving framework core objects
$request = $this->getRequest();
$userSession = $this->getUser();
$response = $this->getResponse();
$controller = $this->getController();
$context = $this->getContext();
// Setting action variables to pass information to the template
$this->setVar('foo', 'bar');
$this->foo = 'bar'; // Shorter version
}
}
Templates
Jeśli akcję zakończymy
return sfView::SUCCESS;
, lub jeśli nie podamy return do wywołania zostanie dołączony szablon actionNameSuccess.php
. Możemy także zwrócić sfView::ERROR
wtedy zostanie dołączony szablon actionNameError.php
, ogólnie symfony szuka w szablonach pliku zwróconego prze return 'MyResult'
+ prefix nazwa akcji.Można też:
return sfView::NONE;
i
$this->getResponse()->setContent("Hello, World!");
return sfView::NONE;
lub
return $this->renderText("Hello, World!");
sobota, 6 września 2008
Symfony krok 2
Definicja bazy danych jest przechowywana w pliku config/schema.yml lub config/schema.xml.
Przykładowy plik xml może wyglądać następująco:
Jeśli chcemy wygenerować plik konfiguracyjny z istniejącej bazy danych wystarczy w pliku config/propel.ini
wyedytować linie:
i wydać komendę:
Dla mnie najprzyjemniejszym narzędziem go graficznego tworzenia baz danych jest wtyczka Clay do Eclipse.
Aby wygenerować klasy reprezentujące tabele w bazie danych (na podstawie pliku xml lub yml) wystarczy wydać polecenie:
Aby symfony mogło połączyć się do bazy danych trzeba wyedytować plik config/database.yml (nie mylić z konfiguracją pluginu propel):
! Ważna uwaga: w plikach yml trzeba używać spacji zamiast tabulatorów.
Jeśli nie mamy gotowej bazy danych możemy wygenerować skrytp sql z konfiguracji schema.xml lub schema.yml:
Przykładowy plik xml może wyglądać następująco:
<?xml version="1.0" encoding="UTF-8"?>
<database name="propel" defaultIdMethod="native" noxsd="true">
<table name="ask_question" phpName="Question">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="user_id" type="integer" />
<foreign-key foreignTable="ask_user">
<reference local="user_id" foreign="id"/>
</foreign-key>
<column name="title" type="longvarchar" />
<column name="body" type="longvarchar" />
<column name="created_at" type="timestamp" />
<column name="updated_at" type="timestamp" />
</table>
<table name="ask_answer" phpName="Answer">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="question_id" type="integer" />
<foreign-key foreignTable="ask_question">
<reference local="question_id" foreign="id"/>
</foreign-key>
<column name="user_id" type="integer" />
<foreign-key foreignTable="ask_user">
<reference local="user_id" foreign="id"/>
</foreign-key>
<column name="body" type="longvarchar" />
<column name="created_at" type="timestamp" />
</table>
<table name="ask_user" phpName="User">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="nickname" type="varchar" size="50" />
<column name="first_name" type="varchar" size="100" />
<column name="last_name" type="varchar" size="100" />
<column name="created_at" type="timestamp" />
</table>
<table name="ask_interest" phpName="Interest">
<column name="question_id" type="integer" primaryKey="true" />
<foreign-key foreignTable="ask_question">
<reference local="question_id" foreign="id"/>
</foreign-key>
<column name="user_id" type="integer" primaryKey="true" />
<foreign-key foreignTable="ask_user">
<reference local="user_id" foreign="id"/>
</foreign-key>
<column name="created_at" type="timestamp" />
</table>
<table name="ask_relevancy" phpName="Relevancy">
<column name="answer_id" type="integer" primaryKey="true" />
<foreign-key foreignTable="ask_answer">
<reference local="answer_id" foreign="id"/>
</foreign-key>
<column name="user_id" type="integer" primaryKey="true" />
<foreign-key foreignTable="ask_user">
<reference local="user_id" foreign="id"/>
</foreign-key>
<column name="score" type="integer" />
<column name="created_at" type="timestamp" />
</table>
</database>
Jeśli chcemy wygenerować plik konfiguracyjny z istniejącej bazy danych wystarczy w pliku config/propel.ini
wyedytować linie:
propel.database.createUrl = mysql://marian@localhost/
propel.database.url = mysql://marian@localhost/askeet
i wydać komendę:
$ symfony propel-build-schema
Dla mnie najprzyjemniejszym narzędziem go graficznego tworzenia baz danych jest wtyczka Clay do Eclipse.
Aby wygenerować klasy reprezentujące tabele w bazie danych (na podstawie pliku xml lub yml) wystarczy wydać polecenie:
$ symfony propel-build-model
Aby symfony mogło połączyć się do bazy danych trzeba wyedytować plik config/database.yml (nie mylić z konfiguracją pluginu propel):
all:
propel:
class: sfPropelDatabase
param:
dsn: mysql://marian@localhost/askeet
! Ważna uwaga: w plikach yml trzeba używać spacji zamiast tabulatorów.
Jeśli nie mamy gotowej bazy danych możemy wygenerować skrytp sql z konfiguracji schema.xml lub schema.yml:
$ symfony propel-build-sql
$ mysql -u youruser -p askeet <> lub
$ symfony propel-insert-sql
$ symfony propel:build-forms
Kolejnym krokiem jest wygenerowanie formularzy do operacji CRUD (miło szybko zobaczyć coś działającego):
// ciekawe że trzeba wykonać ten krok w symfony 1.1 (w askeet tutorial ten krok jest pominięty gdyż tutorial traktuje o symfony 1.0)
// no i właściwy proces generowania$ symfony propel-generate-crud frontend question Question
czwartek, 4 września 2008
System ratownictwa PCK - możliwości usprawnień
Od dłuższego czasu część mojego wolnego czasu poświęcam na wolontariat w grupie ratownictwa PCK w Opolu. Szkolenia dotyczące klęsk żywiołowych, jak i rozmowy z ratownikami dłużej pracującymi w tej formacji przyniosły mi kilka pytań co do możliwości usprawnienia pracy ratowników przy pomocy nowoczesnej technologi.
Jak wygląda akcja ratownicza w obecnym systemie.
W wypadku niespodziewanego kataklizmu czy wypadku zaczyna się od zebrania jak największej ilości informacji o zdarzeniu (jego miejscu, ilości poszkodowanych, warunkach panujących na miejscu zdarzenia itp).
Począwszy od tego miejsca można by wprowadzić usprawnienia które przyśpieszyły by ten proces.
Najważniejsza według mnie jest łączność pomiędzy ratownikami (tymi zbierającymi informacje jak i niosącymi doraźną pomoc poszkodowanym) a kierownictwem akcji ratowniczej. Owszem takowa już istnieje (łączność radiowa na odpowiednio przydzielonych do tego kanałach radiowych) lecz polega ona tylko na głosowym informowaniu kierownictwa. Według mnie powinna istnieć możliwość przesyłania do kierownictwa informacji o położeniu które ciężko opisać słownie.
W terenie gdzie wynikła jakaś katastrofa (np. rozległych budynkach, czy całych miejscowościach) gdzie potrzebna jest pomoc na większym obszarze robione są mapki z rozłożeniem poszkodowanych, obiektów, miejsc niebezpiecznych itp. Problem polega na tym że informacje przynoszone do "centrum dowodzenia" nie są najdokładniejsze. No bo nie każdy jest w stanie prawidłowo określić odległości i w dodatku w czytelny sposób nanieść je na kartkę papieru. Dlaczego nie wykorzystać do tego celu technologi GPS?
Przypuśćmy że w każdej grupie ratowniczej wysyłanej w teren znalazła by się osoba posiadająca odbiornik GPS, mogący w dowolnym momencie połączyć się do "centrum dowodzenia" i wysłać informacje o bieżącej lokalizacji ratowników. Idąc o krok dalej powinna istnieć możliwość zaznaczenia przez ratownika lokalizacji budynków, poszkodowanych i niebezpiecznych miejsc przy pomocy GPS i przesłania ich do kierownictwa akcji. Dane od różnych grup mogły by być połączone w centralnym komputerze i wyświetlone kierującemu akcją. Dało by mu to przybliżony obraz sytuacji i możliwość podjęcia decyzji o kierunku dalszych działań (np. gdzie wysłać więcej ratowników, ile przygotować środków potrzebnych do kontynuacji akcji itp).
Jak wygląda akcja ratownicza w obecnym systemie.
W wypadku niespodziewanego kataklizmu czy wypadku zaczyna się od zebrania jak największej ilości informacji o zdarzeniu (jego miejscu, ilości poszkodowanych, warunkach panujących na miejscu zdarzenia itp).
Począwszy od tego miejsca można by wprowadzić usprawnienia które przyśpieszyły by ten proces.
Najważniejsza według mnie jest łączność pomiędzy ratownikami (tymi zbierającymi informacje jak i niosącymi doraźną pomoc poszkodowanym) a kierownictwem akcji ratowniczej. Owszem takowa już istnieje (łączność radiowa na odpowiednio przydzielonych do tego kanałach radiowych) lecz polega ona tylko na głosowym informowaniu kierownictwa. Według mnie powinna istnieć możliwość przesyłania do kierownictwa informacji o położeniu które ciężko opisać słownie.
W terenie gdzie wynikła jakaś katastrofa (np. rozległych budynkach, czy całych miejscowościach) gdzie potrzebna jest pomoc na większym obszarze robione są mapki z rozłożeniem poszkodowanych, obiektów, miejsc niebezpiecznych itp. Problem polega na tym że informacje przynoszone do "centrum dowodzenia" nie są najdokładniejsze. No bo nie każdy jest w stanie prawidłowo określić odległości i w dodatku w czytelny sposób nanieść je na kartkę papieru. Dlaczego nie wykorzystać do tego celu technologi GPS?
Przypuśćmy że w każdej grupie ratowniczej wysyłanej w teren znalazła by się osoba posiadająca odbiornik GPS, mogący w dowolnym momencie połączyć się do "centrum dowodzenia" i wysłać informacje o bieżącej lokalizacji ratowników. Idąc o krok dalej powinna istnieć możliwość zaznaczenia przez ratownika lokalizacji budynków, poszkodowanych i niebezpiecznych miejsc przy pomocy GPS i przesłania ich do kierownictwa akcji. Dane od różnych grup mogły by być połączone w centralnym komputerze i wyświetlone kierującemu akcją. Dało by mu to przybliżony obraz sytuacji i możliwość podjęcia decyzji o kierunku dalszych działań (np. gdzie wysłać więcej ratowników, ile przygotować środków potrzebnych do kontynuacji akcji itp).
Wiedza, marzenia, pomysły
To niesamowite ile pomysłów chodzi mi po głowie.
Część przychodzi sama z siebie, gdy odpoczywam, słucham muzyki, czy pracuje.
Inne wpadają gdy rozwiązuję jakiś problem czy rozważam usprawnienie jakiejś pracy.
Wszystko to kłębi się w głowie i dojrzewa, część zapisuję, rozważam i szukam sposobów realizacji. Szkoda że nie mam wystarczającej wiedzy w niektórych dziedzinach aby zacząć pracę nad ich realizacją. Szukamy wyjścia - może kolejne studia, np. automatyka i robotyka. A może wystarczy przeczytać kilka książek o rozważanych problemach, lub zostać słuchaczem na interesujących wykładach?
Na pewno zacznę publikować "owoce" moich przemyśleń. A nuż ktoś podpowie mi jak najlepiej zabrać się do ich realizacji.
Ostatnio spotkałem się z opinią że pracujemy i tworzymy po to aby osiągać z tego wymierne zyski. W moim przypadku chyba nie do końca o to chodzi. Samo tworzenie jest dla mnie ogromną frajdą.
Więcej usystematyzowanej wiedzy - to jest rozwiązanie.
Część przychodzi sama z siebie, gdy odpoczywam, słucham muzyki, czy pracuje.
Inne wpadają gdy rozwiązuję jakiś problem czy rozważam usprawnienie jakiejś pracy.
Wszystko to kłębi się w głowie i dojrzewa, część zapisuję, rozważam i szukam sposobów realizacji. Szkoda że nie mam wystarczającej wiedzy w niektórych dziedzinach aby zacząć pracę nad ich realizacją. Szukamy wyjścia - może kolejne studia, np. automatyka i robotyka. A może wystarczy przeczytać kilka książek o rozważanych problemach, lub zostać słuchaczem na interesujących wykładach?
Na pewno zacznę publikować "owoce" moich przemyśleń. A nuż ktoś podpowie mi jak najlepiej zabrać się do ich realizacji.
Ostatnio spotkałem się z opinią że pracujemy i tworzymy po to aby osiągać z tego wymierne zyski. W moim przypadku chyba nie do końca o to chodzi. Samo tworzenie jest dla mnie ogromną frajdą.
Więcej usystematyzowanej wiedzy - to jest rozwiązanie.
środa, 3 września 2008
Nazwa dla nowego projektu...
niby nic trudnego, wystarczy przegrepować słownik (np z kurnikowego słownika) wyrażeniem regularnym
może tak:
hmmm, raczej nie o to mi chodziło - chyba pozostanę przy dłuższej nazwie :)
może tak:
marian@miranda:~/programming/bazy> grep -E '^s.*p.*j.*r.*;' thesaurus-1.5.utf8.txt
spisek;tajne porozumienie;zmowa
hmmm, raczej nie o to mi chodziło - chyba pozostanę przy dłuższej nazwie :)
wtorek, 2 września 2008
symfony i SuSe
Instalacja.
Najprościej skorzystać z PEAR (jest dostępny w repozytorium yast)
Następnie wystarczy wydać komendę:
Tworzenie projektu:
Najprościej skorzystać z PEAR (jest dostępny w repozytorium yast)
Następnie wystarczy wydać komendę:
> pear channel-discover pear.symfony-project.com
> pear remote-list -c symfony
> pear install symfony/symfony
Tworzenie projektu:
> mkdir myproject
> cd myproject
> symfony generate:app frontend
> symfony generate:project myproject
> symfony generate:module frontend content
Ponadto aby testować stronę z dowolnym url musimy dodać wpis do virtualnych hostów.
W suse wystarczy dodać plik z rozszerzeniem .conf do katalogu /etc/apache2/vhosts.d
<virtualhost>
ServerName przykladowa-aplikacja.pl
DocumentRoot "/home/marian/przykladowa-aplikacja/web"
DirectoryIndex index.php
Alias /sf "/usr/share/php5/PEAR/data/symfony/web/sf"
<directory>
AllowOverride All
Allow from All
</directory>
<directory>
AllowOverride All
Allow from All
</directory>
</virtualhost>
Musimy również dodać do /etc/hosts
127.0.0.1 przykladowa-aplikacja.pl
Subskrybuj:
Posty (Atom)