Archiv für die Kategorie ‘PHP’
Freitag, 07. Mai 2010 von sägefisch
Um in Agavi custom logfiles zu erstellen, benötigt man einen eigens erstellten logger + appender in der app/config/logger.xml.
<!-- logs only custom messages in a custom log -->
<logger name="custom" class="AgaviLogger" level="'custom'">
<appenders>
<appender>CustomLogAppender</appender>
</appenders>
</logger>
<appender name="CustomLogAppender" class="AgaviFileLoggerAppender" layout="DateTimeLayout">
<ae:parameters>
<ae:parameter name="file">%core.app_dir%/log/custom.log</ae:parameter>
</ae:parameters>
</appender>
Dann kann man den Logger quasi überall wo der LoggerManager verfügbar ist benutzen.
$message = 'Custom logging message';
$this->getContext()->getLoggerManager()->log(new AgaviLoggerMessage($message, 'custom'), 'custom');
Und in der bash das logfile einsehen.
tail -f app/log/custom.log
Tags:agavi, bash, log, logger, logging, PHP, XML Abgelegt in Agavi, Debugging, Frameworks, Linux, PHP, Shell, XML | Keine Kommentare »
Montag, 30. November 2009 von sägefisch
Ein sehr interessanter Ansatz zur Erzeugung von Dokumenten im Web wird bei phphatesme.com beschrieben. HTML-zu-PDF-Konvertierung und programmatischer Ansatz sind ja bekannt. Der neue Ansatz bedient sich einer SOAP Schnittstelle und Templates. Unter folgender URL gibts mehr dazu:
phphatesme.com – PDF Dokumente mit Zend LiveDocx
Tags:docx, dokument, livedocx, management, pdf, pdf2html, PHP, phphatesme, Zend Abgelegt in Frameworks, PHP, SOAP, Zend | Keine Kommentare »
Freitag, 20. November 2009 von sägefisch
Hier der Link zu PHPBench. Benchmarks für PHP Funktionen.
phpbench.com
Tags:benchmark, PHP, phpbench Abgelegt in Debugging, PHP | Keine Kommentare »
Sonntag, 15. November 2009 von sägefisch
XDebug ist das sehr beliebte und allseits bewährte Tool, das nicht nur Stacktrace und var_dumps ausgeben kann, sondern ebenso für CodeCoverage, echtes Debuggen, Profiling und Testen mit PHPUnit gedacht ist.
XDebug kann Profiler Dateien erzeugen, die man mit KCacheGrind perfekt auswerten kann. So bleibt kein Flaschenhals in der Applikation unbemerkt.
xdebug.org
kcachegrind.sourceforge.net
Tags:code coverage, debug, kcachegrind, PHPUnit, profiling, stacktrace, test, var_dump, XDebug Abgelegt in Debugging, Linux, PHP, PHPUnit, Server, Shell, XDebug | Keine Kommentare »
Dienstag, 10. November 2009 von graste
Für diverse Aufgaben in größeren Projekten ist es notwendig, eigene XML-Konfigurationsdateien zu nutzen. Die Definition umfangreicher Einstellungen in der settings.xml wird schnell anstrengend und das Holen der Werte per AgaviConfig::get('setting.name', 'default'); unübersichtlich. Agavi bietet es aber an, eigene Konfigurationsdateien zu erstellen und diese nicht nur zu validieren, sondern auch zur Wiederverwendung zu cachen.
In der Agavi FAQ habe ich dazu mal ein Beispiel verfasst.
Einfach einen Config-Handler in der config_handlers.xml definieren:
<handler pattern="%core.config_dir%/project/foo/*.xml" class="AgaviReturnArrayConfigHandler" />
und dann direkt in den Actions, Views und Models benutzen:
if (!isset($config['baz']))
{
throw new LogicException('baz is missing!');
}
if (isset($config['bars']))
{
foreach ($config['bars'] as $foo => $data)
{
$this->doSomethingWithEach($foo, $data);
}
}
Die XML-Datei für den obigen Code könnte beispielweise so aussehen:
<ae:configurations>
<ae:configuration>
<baz>asdf</baz>
<foo>-1</foo>
<bars>
<some>...more data and xml...</some>
<more>...more data and xml...</more>
<deep>...more data and xml...</deep>
<structs>...more data and xml...</structs>
</bars>
</ae:configuration>
<ae:configuration environment="production.*">
<baz>bleh</baz>
<foo>1</foo>
</ae:configuration>
</ae:configurations>
Gut zu erkennen ist der Vorteil eigener Configs: Man kann die Agavi-Features für Konfigurationsdateien nutzen und auf einfache Art und Weise environmentspezifische Einstellungen vornehmen (z.B. in “Production” andere Werte für Logdateien, URLs oder Einstellungen nutzen als während der Entwicklung oder beim Testen).
Ebenfalls gut zu erkennen im PHP-Code ist, dass man lauter Abfragen über die Existenz bestimmer Elemente macht, die man sich mit vernünftiger Validierung sparen kann, da invalide XML-Dokumente gar nicht erst als korrekt angesehen werden von Agavi. Um seine XML-Strukturen zu validieren definiert man per validation Parameter ein XML-Schema und definiert noch gleich einen eigenen ConfigHandler, den man schreibt und per autoload.xml bekannt macht:
<handler pattern="%core.config_dir%/project/foo/*.foo.xml" class="FooDefinitionConfigHandler">
<validation>%core.config_dir%/xsd/foo_definition.xsd</validation/>
</handler>
Der ConfigHandler könnte so beginnen:
class FooDefinitionConfigHandler extends AgaviXmlConfigHandler
{
// notwendige Methoden implementieren und XML-Struktur validieren...
}
Für Beispiele einfach in die in Agavi verwendeten XSDs und entsprechende ConfigHandler sehen. Viel Spaß. :)
Tags:agavi, ConfigHandler, Konfiguration, Schema, Validierung, XML, XSD Abgelegt in Agavi, Frameworks, PHP, XML | Keine Kommentare »
Freitag, 30. Oktober 2009 von sägefisch
Hier der komplette PHPUnit Guide um entsprechende Tests zu seiner Applikation zu schreiben.
PHPUnit Manual
Tags:bergmann, guide, PHP, PHPUnit, sebastian, unit Abgelegt in PHP, PHPUnit | Keine Kommentare »
Freitag, 30. Oktober 2009 von sägefisch
Der ultimative Guide für Objektorientierung, Entwurfsmuster und Modellierung sowie fortgeschrittene Datenbankprogrammierung von Sebastian Bergmann
Professionelle Softwareentwicklung mit PHP 5
Tags:datenbanken, mvc, oop, pattern, PHP Abgelegt in MySQL, PHP, PHPUnit | Keine Kommentare »
Sonntag, 25. Oktober 2009 von sägefisch
Um modular und agil in Kohana zu entwickeln, wurde ein Skript Kollektor notwendig, der aus allen Controllern (Template- oder Standard-Controllern) Skripte (CSS, Javascript) sammeln kann.
Diese Scripte werden dann auf den jeweiligen Mastertemplates wieder an den richtigen Stellen eingebunden.
Dazu habe ich einen neuen Helper unter application/helpers/collector.php eingerichtet.
class Collector_Core
{
/**
* Arrays containing URL's to scripts/styles (fill with standards)
* @var string
*/
static protected $scripts = array();
static protected $styles = array();
/**
* Adds a url to store
* @param string $file the local path to file
* @return void
*/
static public function addJs($file)
{
self::$scripts[] = $file;
}
/**
* Adds a url to store
* @param string $file the local path to file
* @return void
*/
static public function addCss($file)
{
self::$styles[] = $file;
}
/**
* Generates/renders collectors items
* @param boolean $print whether to echo the output or just return rendered string
* @return string the rendered output
*/
static public function renderJs($print = false)
{
$scripts = array_unique(self::$scripts);
$output = html::script($scripts);
if ($print)
{
echo $output;
}
else
{
return $output;
}
}
/**
* Generates/renders collectors items
* @param boolean $print whether to echo the output or just return rendered string
* @param string|array $media type for this style (all, screen, print, media)
* @return string the rendered output
*/
static public function renderCss($print = false, $media = 'all')
{
$styles = array_unique(self::$styles);
$output = html::stylesheet($styles, $media);
if ($print)
{
echo $output;
}
else
{
return $output;
}
}
} // end of Collector_Core
Dieser Helper kann nun aus allen Controllern heraus befüllt werden.
class Welcome_Controller extends Template_Controller
{
/**
* set master template
*/
public $template = 'master_default.tpl';
/**
* default constructor
* @param void
* @return void
*/
public function __construct()
{
// load parent constructor
parent::__construct();
// collect scripts and styles
collector::addCss('/css/fancybox');
collector::addJs('/js/jquery.1.3.2');
collector::addJs('/js/jquery.fancybox');
}
/** more code here */
} // end of Welcome_Controller
Nachdem nun alle relevanten Skripte eingesammelt wurden, kann man diese auf dem Template wieder ausgeben lassen.
<?php collector::renderCss(true, 'all'); ?>
<!-- html code here -->
<?php collector::renderJs(true); ?>
Der Kollektor sorgt dafür das keine doppelten Skripte geladen werden.
Tags:collector, controller, css, helper, Javascript, kohana, PHP, script, stylesheet, template Abgelegt in Frameworks, Javascript, Kohana, PHP | Keine Kommentare »
Sonntag, 25. Oktober 2009 von sägefisch
Eine einfache all-in-one Lösung für Standard SOAP Services kann man mit dem Kohana Framework und der Zend Bibliothek realisieren.
Dazu bedarf es lediglich eines Kohana Frontcontrollers über den wir den Service und die WSDL ansprechen können.
Zur automatischen Generierung der WSDL, bedienen wir uns hier der Zend AutoDiscover Klasse. Dieser Klasse übergibt man lediglich die ServiceModel-Klasse mit enthaltenen Annotationen, die die Servicefunktionen enthält.
Aus den Annotationen generiert Zend AutoDiscover eine passende WSDL.
/**
* include libs and models
*
*/
include('Zend/Soap/AutoDiscover.php');
include(APPPATH . 'models/service.php');
/**
* this class represents a controller
* application/controllers/soap.php
*
* @package SOAPService
* @subpackage ...
* @author saegefisch (xxx@xxx.xx)
* @copyright (c) 2009 xxx
*/
class Soap_Controller extends Controller
{
/**
* default constructor
*
* @param void
* @return void
*/
public function __construct()
{
// load parent constructor
parent::__construct();
}
/**
* service to call
*
* @param void
* @return void
*/
public function service()
{
// disable wsdl cache
ini_set('soap.wsdl_cache_enabled', '0');
// set auth settings if needed
$settings = array(
'login' => 'user',
'password' => 'password',
'authentication' => SOAP_AUTHENTICATION_BASIC,
'soap_version' => SOAP_1_2,
'encoding' => 'UTF-8',
'cache_wsdl' => WSDL_CACHE_NONE
);
// include user:password if needed
$wsdl = 'http://user:password@' . $_SERVER['HTTP_HOST'] . '/soap/wsdl';
$server = new SoapServer($wsdl, $settings);
$server->setClass('Service_Model');
$server->handle();
}
/**
* wsdl to call
*
* @param void
* @return void
*/
public function wsdl()
{
// disable wsdl cache
ini_set('soap.wsdl_cache_enabled', '0');
$wsdl = new Zend_Soap_AutoDiscover();
$wsdl->setUri('http://' . $_SERVER['HTTP_HOST'] . '/soap/service');
$wsdl->setClass('Service_Model');
$wsdl->handle();
}
}
Hier stellen wir das Standard Model für unseren SOAP Service zusammen.
/**
* this class represents a model
* application/models/service.php
*
* @package SOAPService
* @subpackage ...
* @author saegefisch (xxx@xxx.xx)
* @copyright (c) 2009
*/
class Service_Model extends Model
{
/**
* default constructor
*
* @param void
* @return void
*/
public function __construct()
{
// load database library into $this->db (can be omitted if not required)
parent::__construct();
}
/**
* dummy function
*
* @param int $int
* @param string $string
* @param array $arr
* @param object $obj
* @param bool $bool
* @return array
*/
public function get_dummy_array($int, $string, $arr, $obj, $bool)
{
return array();
}
/**
* dummy function
*
* @param int $int
* @param string $string
* @param array $arr
* @param object $obj
* @param bool $bool
* @return bool
*/
public function get_dummy_boolean($int, $string, $arr, $obj, $bool)
{
return true;
}
/**
* dummy function
*
* @param int $int
* @param string $string
* @param array $arr
* @param object $obj
* @param bool $bool
* @return string
*/
public function get_dummy_string($int, $string, $arr, $obj, $bool)
{
return 'foo=bar';
}
}
Tags:autodiscover, controller, generator, kohana, model, service, soa, SOAP, wsdl, Zend Abgelegt in Kohana, PHP, SOAP, Zend | Keine Kommentare »
Sonntag, 25. Oktober 2009 von sägefisch

Die Propel ORM für PHP bedient sich einer eigenen Syntax (Criterias) um Queries zusammenzustellen.
Hier gibt es einen Criteria Builder, den man mit Standard SQL füttern kann.
Der Criteria Builder konvertiert sodann das eingegebene SQL Statement in ein Propel Criteria.
So wird aus diesem kleinen SQL Statement:
SELECT user.*
FROM user
WHERE user.state = 100
AND (user.name = 'user' OR user.email = 'user@domain.tld')
diese Propel Criteria:
$c = new Criteria();
$crit0 = $c->getNewCriterion(UserPeer::STATE, 100);
$crit1 = $c->getNewCriterion(UserPeer::NAME, 'user');
$crit2 = $c->getNewCriterion(UserPeer::EMAIL, 'user@domain.tld');
// Perform OR at level 1 ($crit1 $crit2 )
$crit1->addOr($crit2);
// Perform AND at level 0 ($crit0 $crit1 )
$crit0->addAnd($crit1);
// Remember to change the peer class here for the correct one in your model
$c->add($crit0);
$result = TablePeer::doSelect($c);
// This loop will of course need to be edited to work
foreach ($result as $obj)
{
//$val = $obj->getValue();
}
Einen Versuch ist es Wert.
Hier gehts zum Propel ORM Criteria Builder
Tags:builder, criteria, MySQL, orm, propel, query, sql Abgelegt in MySQL, PHP, Propel ORM | Keine Kommentare »
|
|