<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>API | Nerdpress.org</title>
	<atom:link href="https://nerdpress.org/tag/api/feed/" rel="self" type="application/rss+xml" />
	<link>https://nerdpress.org</link>
	<description>...dev, tech problems and solutions.</description>
	<lastBuildDate>Mon, 02 Oct 2017 05:49:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Splitting Swagger API Documentation yaml files</title>
		<link>https://nerdpress.org/2017/10/01/splitting-swagger-api-documentation-yaml-files/</link>
					<comments>https://nerdpress.org/2017/10/01/splitting-swagger-api-documentation-yaml-files/#comments</comments>
		
		<dc:creator><![CDATA[Max Girkens]]></dc:creator>
		<pubDate>Sun, 01 Oct 2017 06:00:22 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[swagger]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=2777</guid>

					<description><![CDATA[<p>When documenting your API with Swagger/Swagger-UI, one really cool feature to use is the $ref syntax. As Swagger documentation files tend to get real large und hard too read, splitting the config across multiple files might be a good idea. With $ref you could do this quite easily. For example you could reference a single &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2017/10/01/splitting-swagger-api-documentation-yaml-files/" class="more-link">Continue reading<span class="screen-reader-text"> "Splitting Swagger API Documentation yaml files"</span></a></p>
The post <a href="https://nerdpress.org/2017/10/01/splitting-swagger-api-documentation-yaml-files/">Splitting Swagger API Documentation yaml files</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>When documenting your API with <a href="https://swagger.io/swagger-ui/">Swagger/Swagger-UI</a>, one really cool feature to use is the <em>$ref</em> syntax.</p>
<p>As Swagger documentation files tend to get real large und hard too read, splitting the config across multiple files might be a good idea.<br />
With <em>$ref</em> you could do this quite easily.<br />
<span id="more-2777"></span><br />
For example you could reference a single config file per path like so:</p>
<pre class="brush: yaml; title: ; notranslate">
swagger: &quot;2.0&quot;
basePath: &quot;my-api/v1/&quot;
info:
  version: &quot;0.0.1&quot;
  title: &quot;my API&quot;
tags:
  - name: &quot;section1&quot;
    description: &quot;Some Section&quot;
  - name: &quot;section2&quot;
    description: &quot;Some other Section&quot;

paths:

  ##section 1

  /section1/some/path:
    $ref: 'paths/section1_some_path.yml'

  /section1/some-other-path:
    $ref: 'paths/section1_some_other_path.yml'
</pre>
<p>Then have all actions for this path defined in a dedicated file like this:</p>
<p><strong>paths/section1_some_path.yml:</strong></p>
<pre class="brush: yaml; title: ; notranslate">
post:
  tags:
  - &quot;section1&quot;
  parameters:
    ...
</pre>
<p>This really helped me managing larger documentation files, which otherwise tend to get quite hard to read.</p>The post <a href="https://nerdpress.org/2017/10/01/splitting-swagger-api-documentation-yaml-files/">Splitting Swagger API Documentation yaml files</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2017/10/01/splitting-swagger-api-documentation-yaml-files/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>mashcloud.net &#8211; mashup soundcloud audio tracks</title>
		<link>https://nerdpress.org/2013/01/24/mashcloud-net-mashup-soundcloud-audio-tracks/</link>
		
		<dc:creator><![CDATA[Max Girkens]]></dc:creator>
		<pubDate>Thu, 24 Jan 2013 20:08:28 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Express]]></category>
		<category><![CDATA[Frontend]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[socket.io]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[sockets]]></category>
		<category><![CDATA[soundcloud]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=2359</guid>

					<description><![CDATA[<p>mashcloud.net is an experiment on collaborative realtime audio editing and music creation. I did the project within the frame of  my BA thesis in audio production last year. As I moved the code to github this week, I wanted to give a quick overview of the project and its technical underlyings, just in case someone might &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2013/01/24/mashcloud-net-mashup-soundcloud-audio-tracks/" class="more-link">Continue reading<span class="screen-reader-text"> "mashcloud.net &#8211; mashup soundcloud audio tracks"</span></a></p>
The post <a href="https://nerdpress.org/2013/01/24/mashcloud-net-mashup-soundcloud-audio-tracks/">mashcloud.net – mashup soundcloud audio tracks</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p><a href="http://mashcloud.net/">mashcloud.net</a> is an experiment on collaborative realtime audio editing and music creation. <br />I did the project within the frame of  my BA thesis in audio production last year.</p>
<p>As I moved the code to <a href="https://github.com/gherkins/mashcloud">github</a> this week, I wanted to give a quick overview of the project and its technical underlyings, just in case someone might be interested :)</p>
<p><span id="more-2359"></span>As the title of this post might already suggest, its about selecting and layering loops from audiofiles hosted on <a href="http://soundcloud.com">soundcloud.com</a> and thereby creating new music.</p>
<p><a href="https://nerdpress.org/2013/01/24/mashcloud-net-mashup-soundcloud-audio-tracks/bildschirmfoto-2013-01-24-um-20-46-08/" rel="attachment wp-att-2363"><img fetchpriority="high" decoding="async" class="alignnone size-medium wp-image-2363" alt="Bildschirmfoto 2013-01-24 um 20.46.08" src="https://nerdpress.org/wp-content/uploads/2013/01/Bildschirmfoto-2013-01-24-um-20.46.08-300x174.png" width="300" height="174" srcset="https://nerdpress.org/wp-content/uploads/2013/01/Bildschirmfoto-2013-01-24-um-20.46.08-300x174.png 300w, https://nerdpress.org/wp-content/uploads/2013/01/Bildschirmfoto-2013-01-24-um-20.46.08-1024x593.png 1024w, https://nerdpress.org/wp-content/uploads/2013/01/Bildschirmfoto-2013-01-24-um-20.46.08.png 1050w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Those collections of layered loops are called a session. Sessions can be created anonymously by everyone and are auto-saved on every action. By distributing the URL of a session other users can join and every action is synced between all users in realtime. <br />(complete mayhem, indeed :)</p>
<p>The application is built with HTML5 and JS w/ <a href="http://jquery.com/">jQuery</a> using the <a href="http://developers.soundcloud.com/docs/api/guide">soundcloud API</a> on the client side and runs on <a href="http://nodejs.org/">node.js</a> &amp; <a href="http://www.mongodb.org/">mongoDB</a> with <a href="http://expressjs.com/">express</a>, <a href="http://socket.io/">socket.io</a> and <a href="http://mongoosejs.com/">mongoose</a> on the server side.</p>
<p>I basically started the project to find out if you could play multiple loops asynchronous and synced with low latency using the <a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html">Web Audio API</a> while collaboratively working together with multiple users in realtime. </p>
<p>As that turned out to be not only possible but performed real nicely, the experiment then developed in somewhat of an application and finally got a name and a face.</p>
<p>There&#8217;s a whole lot of things i&#8217;d like to implement / refactor and do when i get some time on my hands, as</p>
<p>&#8211; adding a &#8220;record&#8221; feature to record, save and export created sessions as audiofiles</p>
<p>&#8211; rewriting the client side with <a href="http://backbonejs.org/">backbone.js</a> (as things got a bit messy &#8230;)</p>
<p>&#8211; adding some audio effects to the tracks</p>
<p>&#8211; write some tests</p>
<p>I&#8217;d appreciate any form of contribution as much as any questions or feedback on the project :)</p>
<p>Feel free to check out the live version at <a href="http://mashcloud.net/"> http://mashcloud.net/</a> or the sources at <a href="https://github.com/gherkins/mashcloud">https://github.com/gherkins/mashcloud</a></p>The post <a href="https://nerdpress.org/2013/01/24/mashcloud-net-mashup-soundcloud-audio-tracks/">mashcloud.net – mashup soundcloud audio tracks</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dependency Injection mit PHP 5.3, Runkit-Erweiterung und Doctrine 2-Annotationen</title>
		<link>https://nerdpress.org/2010/09/26/dependency-injection-mit-php-5-3-runkit-erweiterung-und-doctrine-2-annotationen/</link>
					<comments>https://nerdpress.org/2010/09/26/dependency-injection-mit-php-5-3-runkit-erweiterung-und-doctrine-2-annotationen/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sun, 26 Sep 2010 15:33:33 +0000</pubDate>
				<category><![CDATA[Doctrine ORM]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software engineering]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Annotations]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Doctrine 2]]></category>
		<category><![CDATA[IoC]]></category>
		<category><![CDATA[PHP 5.3]]></category>
		<category><![CDATA[Runkit]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1085</guid>

					<description><![CDATA[<p>Unter Dependency Injection versteht man heute nicht nur ein einfaches Entwurfsmuster, sondern vor allem Framework-gestützte Mechanismen, die den konkreten Implementierungsaufwand verringern (Entwicklungszeitoptimierung), dem Entwickler bessere Übersicht über Abhängigkeiten zu schaffen (Applicationdesignoptimierung) und die Anzahl der Instanzen gleichen Prototyps zu minimieren (Performanceoptimierung). Heute möchte ich einen alternativen, vielleicht pragmatischeren Ansatz als der andererer populärer Implementierungenn herbeispinnen, &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2010/09/26/dependency-injection-mit-php-5-3-runkit-erweiterung-und-doctrine-2-annotationen/" class="more-link">Continue reading<span class="screen-reader-text"> "Dependency Injection mit PHP 5.3, Runkit-Erweiterung und Doctrine 2-Annotationen"</span></a></p>
The post <a href="https://nerdpress.org/2010/09/26/dependency-injection-mit-php-5-3-runkit-erweiterung-und-doctrine-2-annotationen/">Dependency Injection mit PHP 5.3, Runkit-Erweiterung und Doctrine 2-Annotationen</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Unter <a href="http://de.wikipedia.org/wiki/Dependency_Injection">Dependency Injection</a> versteht man heute nicht nur ein einfaches Entwurfsmuster, sondern vor allem Framework-gestützte Mechanismen, die den konkreten Implementierungsaufwand verringern (Entwicklungszeitoptimierung), dem Entwickler bessere Übersicht über Abhängigkeiten zu schaffen (Applicationdesignoptimierung) und die Anzahl der Instanzen gleichen Prototyps zu minimieren (Performanceoptimierung).</p>
<p>Heute möchte ich einen alternativen, vielleicht pragmatischeren Ansatz als der andererer populärer Implementierungenn herbeispinnen, um Dependency Injection (DI) in PHP 5.3 zu realisieren.<br />
<span id="more-1085"></span><br />
Für diverse Programmiersprachen gibt es &#8211; auf den jeweiligen Anwendungsbereich mehr oder weniger spezialisierte &#8211; sogenannte Dependency-Injection (DI)-Container. Der DI-Container als solcher dient im Grunde als Manager oder Konfigurator, der das Zusammenspiel unserer Abhängigkeiten definiert &#8211; meist auf Grundlage einer Konfigurationsdatei, die bspw. in XML vorliegt:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&quot;&gt;

  &lt;bean id=&quot;...&quot; class=&quot;...&quot;&gt;
    &lt;!-- collaborators and configuration for this bean go here --&gt;
  &lt;/bean&gt;

  &lt;bean id=&quot;...&quot; class=&quot;...&quot;&gt;
    &lt;!-- collaborators and configuration for this bean go here --&gt;
  &lt;/bean&gt;

  &lt;!-- more bean definitions go here... --&gt;

&lt;/beans&gt;
</pre>
<p>(Quelle: <a href="http://static.springsource.org/spring/docs/2.0.x/reference/beans.html">Springsource</a>)</p>
<p>Eine weitere Möglichkeit Abhängigkeiten zu definieren, bietet das <a href="http://en.wikipedia.org/wiki/Convention_over_configuration">Convention Over Configuration-Paradigma</a>: Heißt bspw. eine Member-Variable &#8220;Mailservice&#8221;, so kann der zugrundeliegende DI-Container entsprechend konfiguriert werden, sodass bei Instanziierung automatisch eine Klasse gleichen Namens (Mailservice) instanziiert und an das Objekt gebunden wird (so macht&#8217;s bspw. Grails in seinen MVC-Controller-Instanzen, wobei hier natürlich wieder das <a href="http://static.springsource.org/spring/docs/2.0.x/reference/beans.html">Spring IoC</a> (Das hat nichts mit dem internationalen olympischen Komitee zu tun, sondern ist die Abkürzung für &#8220;Inversion of Control&#8221; und steht gleichbedeutend für &#8220;Dependency Injection&#8221;). Diese Implementierung erfordert natürlich ausgereifte Introspektionsmechanismen der zugrundeliegenden Programmiersprache (Stichwort &#8220;<a href="http://de.wikipedia.org/wiki/Reflexion_(Programmierung)">Reflection</a>&#8220;), außerdem muss man dem DI bzw. IOC-Container vorher beigebracht haben, <em>welche</em> Klassen oder Verzeichnisstrukturen überhaupt durchsucht und unter &#8220;DI-Kontrolle&#8221; gestellt werden müssen &#8211; ein zusätzlicher Programmieraufwand ist also immer noch gegeben. Unvorhersehbarkeiten im Code und eine erhöhte WTF&#8217;s/min-Rate kommen dabei frei Haus.</p>
<p>PHP bieted zu dem ganzen Thema ab Werk erstmal &#8211; nix. Die <a href="http://php.net/manual/en/book.reflection.php">Reflection-API</a> ist aber schonmal ein ausgereiftes Werkzeug, um definierte Abhängigkeiten auszuwerten. Das allerdings ausschließlich mittels lesendem Zugriff auf Metadaten von bspw. Klassen, Methoden oder auch System- bzw. benutzerdefinierten Funktionen. Schreibende Operationen sind im Sprachkern erst einmal nicht vorgesehen. Es ist also prinzipiell möglich, zur Laufzeit Abhängigkeiten durch Konvention zu definieren, die Auflösung selbiger ist aber &#8220;mit Boardmitteln&#8221; nicht zu realisieren. </p>
<p>Ein eigenes Sprachkonstrukt wie <a href="http://de.wikipedia.org/wiki/Mixin">Mixins</a> ist auch (noch) nicht implementiert, und anonyme (&#8220;<a href="http://de.wikipedia.org/wiki/Lambda-Funktion">Lambda</a>&#8220;)-Funktionen lassen sich nicht wie in Javascript oder auch Groovy direkt an den Objekt-Prototypen hängen oder auch an einzelne Instanzen, sondern müssen mühsam &#8220;by reference&#8221; gezogen und dann erst ausgewertet werden.</p>
<p>Javascript:</p>
<pre class="brush: jscript; title: ; notranslate">
  var foo = function() { }
  foo.prototype.bar = function() { return &quot;bar&quot;; }
  foo.baz = foo.prototype.bar;

  var foobar = new foo;
  foo.bar(); // -&gt; &quot;bar&quot;
  foo.baz(); // -&gt; &quot;bar&quot;
</pre>
<p>PHP:</p>
<pre class="brush: php; title: ; notranslate">
  $foo = new stdClass();
  $foo-&gt;bar = function() 
  {
    return &quot;bar&quot;;
  }
  $foo-&gt;bar(); // method not found
   
  $bar = $foo-&gt;bar;
  $bar(); // -&gt; &quot;bar&quot;
</pre>
<p>Zugegeben: Gäbe es bereits Mixins oder Prototypen im PHP-Kontext, wäre die Implementierung eines DI-Containers wohl eher unspannend, mindestens aber überflüssig. Dennoch fehlt eine zuverlässige Möglichkeit, PHP-Instanzen zur Laufzeit mit neuen Methoden anreichern zu können. Daher gehen die meisten PHP-DI-Frameworks immer den Weg über einen recht aufgeblähten DI-Container. Dieser macht aber im Grunde nichts anderes, als Referenzen zu verwalten. Der Container selbst wird dann an die anzureichernde Instanz gebunden, im Idealfall eventuell aber noch via magischer Methode __call() verborgen. Dann aber muss die zu aufnehmende Instanz wiederum mindestens ein Interface &#8220;Injectable&#8221;  o.Ä. implementieren. Letzlich aber passiert am Ende immer folgendes:</p>
<pre class="brush: php; title: ; notranslate">
class myController extends Controller
{
  public function indexAction(HttpRequest $request)
  {
    $db = $this-&gt;getService('Database');
  }
}
</pre>
<p>Der Service-Container übernimmt also die klassische Aufgabe des &#8220;ApplicationContext&#8221;: Er managed Referenzen, rückt diese aber erst &#8220;on demand&#8221; heraus. Meiner Meinung hat man dabei nicht allzu viel gewonnen, vor allem, wenn das obige Codeschnippsel noch eine Menge Konfiguration, Code zum Bootstrappen des DI-Containers und/oder Caching voraussetzt.</p>
<p>Ich persönlich würde mir dann doch eher &#8220;ganz oldschool&#8221; ein paar getter/setter zusätzlich schreiben und mich einfach darauf verlassen, dass der gute, alte ApplicationContext sowieso (fast) alles enthält, was ich brauch&#8217;, mit der Konsequenz, dass dieser eben nicht gerade leichtgewichtig ist.</p>
<p>Wozu also das ganze?</p>
<h2>Ein alternativer DI-Container mit Doctrine 2 Annotations und Runkit</h2>
<p>Die Annotations-Implementierung von Doctrine 2 ist einfach und mächtig genug, um eine beliebigen Klasse mit Metainformationen auszustatten, die die zu injizierenden Abhängigkeiten definieren. Runkit ermöglicht es, auf Basis dieser Metadaten Abhänigkeiten an das ensprechende Objekt zu binden &#8211; zur Laufzeit und ohne zusätzliche Implementierung von Schnittstellen o.Ä. Vom Prinzip her sollte es also möglich sein, eine Klasse zu schreiben, diese zu annotieren und dann bei Instanziierung automatisch alle gewünschten Abhängigkeiten zur Verfügung stehen zu haben. Ein Codebeispiel:</p>
<p>index.php:</p>
<pre class="brush: php; title: ; notranslate">
  require __DIR__ . '/lib/vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php';

  use DoctrineCommonClassLoader;
  
  $classLoader = new ClassLoader('DoctrineCommon', __DIR__ . '/lib/vendor/doctrine-common/lib');
  $classLoader-&gt;register();

  $classLoader = new ClassLoader('deifschleife', __DIR__ . '/lib');
  $classLoader-&gt;register();

  // INITIALISIERUNG DES DI-CONTAINERS
  $di_container = new deifschleifediContainer;
  
  $di_container-&gt;setClassnames(array(
    'deifschleifeDITest'
  ));
  
  // &quot;AUFNEHMENDE&quot; KLASSE
  $test = new deifschleifeDITest();

  // GEHÖRT deifschleifeADependency
  echo $test-&gt;foo();
  
  // GEHÖRT deifschleifeAnotherDependency
  echo $test-&gt;bar();

  // GEHÖRT deifschleifeYetAnotherDependency
  echo $test-&gt;baz();
  
  // GIBT's NICHT, ÜBER __call() ABGEFANGEN
  echo $test-&gt;methodThatDoesNotExist();
</pre>
<p>Kurz erklärt:</p>
<pre class="brush: php; title: ; notranslate">
$di_container = new deifschleifediContainer;
$di_container-&gt;setClassnames(array(
    'deifschleifeDITest'
  ));
</pre>
<p>Instanziiert den DI-Container und stellt eine Klasse (deifschleifeDITest) unter seine &#8220;Kontrolle&#8221;.</p>
<pre class="brush: php; title: ; notranslate">
$test = new deifschleifeDITest();

  // GEHÖRT deifschleifeADependency
  echo $test-&gt;foo();
  
  // GEHÖRT deifschleifeAnotherDependency
  echo $test-&gt;bar();

  // GEHÖRT deifschleifeYetAnotherDependency
  echo $test-&gt;baz();
  
  // GIBT's NICHT, ÜBER __call() ABGEFANGEN
  echo $test-&gt;methodThatDoesNotExist();
</pre>
<p>Instanziiert die überwachte Klasse deifschleifeDITest und ruft einige Methoden auf, die sämtlich aus anderen Klassen nach DITest injiziert wurden. Die letze Methode ist nirgends existent. deifschleifeDITest implementiert ausschließlich __call(), ansonsten ist die Klasse (fast) leer:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
namespace deifschleife;

/**
 * @Services({
 *   @Service(
 *    class=&quot;deifschleifeADependency&quot;,
 *    constructorArgs={
 *      &quot;pong&quot;
 *    }
 *  ),
 *  @Service(
 *    class=&quot;deifschleifeAnotherDependency&quot;,
 *    constructor={&quot;deifschleifeAnotherDependency&quot;, &quot;getAnotherDependency&quot;}
 *  ),
 *  @Service(
 *    class=&quot;deifschleifeYetAnotherDependency&quot;,
 *    constructor=&quot;makeYetAnotherDependency&quot;
 *  )
 * })
 */
class DITest
{
  public function __call($method, $args)
  {
    return sprintf(&quot;Called __call, Method: %s, Args: %s&quot;, $method . '()', implode(', ', $args));
  }

  public function makeYetAnotherDependency()
  {
    return new YetAnotherDependency();
  }
}
</pre>
<p>Interessant sind die Klassen-Annotationen ganz oben: @Services teilt dem Doctrine 2 Annotation Parser mit, dass hier eine Reihe von PHP-Klassen, die zu injizierende Methoden enthalten, zusammenzusuchen sind. Jeder einzelne @Service in der Liste kann noch grob konfiguriert werden, so kann bspw. eine eigene Factory-Methode für jede Dependency angegeben werden.</p>
<p>Die einzelnen Dependencies sind &#8220;ganz normale&#8221; PHP-Klassen. Intern passiert folgendes: Die Runkit-Erweiterung dient dazu, über runkit_method_add() &#8220;on the fly&#8221; eine magische Methode __call() an die mit zusätzlcihen Methoden anzureichernde Klasse deifschleifeDITest zu binden. Existiert bereits eine entsprechende Methode __call(), wird diese intern via runkit_method_rename() umbenannt und am Ende von __call() (neu) aufgerufen. Das bedingt natürlich eine gewisse Rücksichtname bei zusätzlicher Verwendung von __call(). </p>
<p>Die Idee unterscheidet sch also nur unwesentlich von bereits vorhandenen Konzepten, spart aber einige Schritte ein:</p>
<p>1.) Man benötigt keine Abstrakte Klasse und/oder Interface, die dass die getService()-Logik bereitstellt.<br />
2.) Man benötigt kaum zusätzliche Konfigurationsaufwand &#8211; eine einfache Annotation im PHPDOc-Comment-Format reicht aus (es spricht allerdings nichts dagegen, je nach Gschmäckle einen Config-Adapter dazwischen zu schieben, der das Mapping via XML oder bspw. Yaml erlaubt)<br />
3.) Man kann auf Proxy-Instanzen verzichten, die __call() transparent bereitstellen.</p>
<p>Fazit: Es ist prinzipiell möglich, Dependency Injection &#8211; passender noch &#8220;Mixins&#8221; &#8211; mit PHP zu realisieren, ohne nennenswert viel Codeoverhead zu produzieren. </p>
<p>Allerdings muss man berücksichtigen, dass Runkit eine experimentelle Erweiterung ist, deren Zuverlässigkeit in komplexen Projekten nicht vorauszusehen ist. Außerdem wird es sehr wahrscheinlich in Bälde ein mächtiges, neues Sprachkonstrukt geben, das Mixins ermöglicht (siehe <a href="http://wiki.php.net/rfc/traits">RFC zu Traits</a>). Und natürlich kann ich mir auch totalen Murks zusammen gereimt haben, denn sicherlich sind die existierenden Implementierungen von fähigeren Architekten entworfen worden und haben bestimmt ihre Daseinsberechtigungen in einem Kontext, den ich vielleicht einfach noch nicht erfasst haben. Comments dazu wären wir sehr willkommen!</p>
<h2>Ausblick</h2>
<p>Die Lösung zentral über __call() ist die Schnelle, aber nicht optimale. Vorstellbar ist eine injizierung sämtlicher öffentlicher Methoden wie runkit_method_add, und ein globaler Accessor, der die Objektinstanz der Abhängigkeit liefert. Das ganze könnte man (optional) konfigurierbar gestalten (über Doctrine 2 Annotationen), um eventuellen Namenskonflikten auszuweichen.</p>
<h2>Test-Sourcen</h2>
<p>Die PHP-Quelltexte zu den obigen Beispielen kann man hier herunterladen:<br />
<a href="http://ifschleife.de/dependency_injection.tar.gz">http://ifschleife.de/dependency_injection.tar.gz</a></p>
<p>Ich habe die DoctrineCommon-Package bereits beigelegt, das Beispiel sollte also unter PHP5.3 funktionieren (bitte di.php aufrufen, der Rest ist noch durchsetzt mit Doctrine 2 Testklamotten).</p>
<p>Eine Anleitung, wie man Runkit unter php5.3 zum laufen kriegt, gibt es <a href="http://d.hatena.ne.jp/shimooka/20100729/1280379407">hier</a> (Japanisch, aber der Quelltext ist auf PHP ;))</p>
<p>Die Test-Sourcen liegen, wie in den obigen Codebeispielen beschrieben, unter lib/de/ifschleife. Ich möchte betonen, dass das nur eine Art Fallstudie ist, ich wäre aber über jeden Kommentar erfreut, der mir widerlegt oder bestätigt, ob man den programmatischen Ansatz vielleicht weiterverfolgen sollte. </p>
<p>Vielen Dank für die Aufmerksamkeit! :)</p>The post <a href="https://nerdpress.org/2010/09/26/dependency-injection-mit-php-5-3-runkit-erweiterung-und-doctrine-2-annotationen/">Dependency Injection mit PHP 5.3, Runkit-Erweiterung und Doctrine 2-Annotationen</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2010/09/26/dependency-injection-mit-php-5-3-runkit-erweiterung-und-doctrine-2-annotationen/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Audio auf Webseiten mit SoundManager 2</title>
		<link>https://nerdpress.org/2009/11/29/audio-auf-webseiten-mit-soundmanager-2/</link>
		
		<dc:creator><![CDATA[Max Girkens]]></dc:creator>
		<pubDate>Sun, 29 Nov 2009 14:28:15 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[mySound]]></category>
		<category><![CDATA[mySoundObject]]></category>
		<category><![CDATA[peakData]]></category>
		<category><![CDATA[soundManager]]></category>
		<category><![CDATA[Sounds]]></category>
		<category><![CDATA[waveform]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=625</guid>

					<description><![CDATA[<p>Audio auf Webseiten ist ja immer so ein Thema. Die &#8220;nativen&#8221; HTML &#8220;Möglichkeiten&#8221; lassen wir mal lieber aussen vor. Des Rätsels Lösung ist ja eigentlich meistens Flash &#8211; so auch bei Soundmanager 2. Nur bleibt Flash hier komplett im Hintergrund und wird nur als &#8220;Ausgabegerät&#8221; missbraucht. Sounds lassen sich dann mittles einer wirklich mal sehr &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2009/11/29/audio-auf-webseiten-mit-soundmanager-2/" class="more-link">Continue reading<span class="screen-reader-text"> "Audio auf Webseiten mit SoundManager 2"</span></a></p>
The post <a href="https://nerdpress.org/2009/11/29/audio-auf-webseiten-mit-soundmanager-2/">Audio auf Webseiten mit SoundManager 2</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Audio auf Webseiten ist ja immer so ein Thema.<br />
Die &#8220;nativen&#8221; HTML &#8220;Möglichkeiten&#8221; lassen wir mal lieber aussen vor.</p>
<p>Des Rätsels Lösung ist ja eigentlich meistens Flash &#8211; so auch bei <a href="http://www.schillmania.com/projects/soundmanager2">Soundmanager 2</a>.<br />
Nur bleibt Flash hier komplett im Hintergrund und wird nur als &#8220;Ausgabegerät&#8221; missbraucht.</p>
<p>Sounds lassen sich dann mittles einer wirklich mal <strong>sehr</strong> coolen JS API einbinden, triggern und noch einiges mehr.<br />
Dazu ist das ganze auch noch <a href="http://www.schillmania.com/projects/soundmanager2/doc/">hervorragend dokumentiert</a>.<span id="more-625"></span></p>
<p>Im einfachsten Fall sieht sowas dann so aus:</p>
<pre class="brush: jscript; title: ; notranslate">
var mySoundObject = soundManager.createSound({
 id: &#039;mySound&#039;,
 url: &#039;/audio/mysoundfile.mp3&#039;
});

mySoundObject.play();
</pre>
<p>soweit so praktisch schonmal.<br />
Die <a href="http://www.schillmania.com/projects/soundmanager2/demo/mpc/">Performance</a> ist übrigens ebensfalls hervorragend.</p>
<p>Richtig gut wird es dann, wenn man Flash 9 vorrausetzt:</p>
<pre class="brush: jscript; title: ; notranslate">
waveformData array: 
256 waveform data values available while playing sound

eqData array: 
256 EQ spectrum data values available while playing sound

peakData object: 
Left and right channel peak/volume data available while playing sound
</pre>
<p>damit lassen sich dann mal eben eigene Meter Darstellungen skripten. In JS.</p>
<p>someSoundObject.whileplaying = function() {<br />
  // Move 256 absolutely-positioned 1&#215;1-pixel DIVs, for example (ugly, but works)<br />
  var gPixels = document.getElementById(&#8216;graphPixels&#8217;).getElementsByTagName(&#8216;div&#8217;);<br />
  var gScale = 32; // draw -32 to +32px from &#8220;zero&#8221; (i.e., center Y-axis point)<br />
  for (var i=0; i<256; i++) {
    graphPixels[i].style.top = (gScale+Math.ceil(this.waveformData[i]*-gScale))+'px';
  }
}
[/sourcecode]

HTML Canvas beispiel : <a href="http://www.schillmania.com/projects/soundmanager2/demo/360-player/canvas-visualization.html">http://www.schillmania.com/projects/soundmanager2/demo/360-player/canvas-visualization.html</a></p>
<p>benutzt wird das ganze übrigens unter anderem von:<br />
<a href="http://muxtape.com/">http://muxtape.com/</a><br />
<a href="http://thecloudplayer.com/">http://thecloudplayer.com/</a><br />
<a href="http://8tracks.com/">http://8tracks.com/</a><br />
und natürlich <a href="http://openchords.org">http://openchords.org</a>  ;)</p>The post <a href="https://nerdpress.org/2009/11/29/audio-auf-webseiten-mit-soundmanager-2/">Audio auf Webseiten mit SoundManager 2</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tiny URLs mit PHP und der tinyurl API</title>
		<link>https://nerdpress.org/2009/10/15/tiny-urls-mit-php-und-de-tinyurl-api/</link>
					<comments>https://nerdpress.org/2009/10/15/tiny-urls-mit-php-und-de-tinyurl-api/#comments</comments>
		
		<dc:creator><![CDATA[Max Girkens]]></dc:creator>
		<pubDate>Thu, 15 Oct 2009 11:38:59 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[tinyurl]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=409</guid>

					<description><![CDATA[<p>für den Fall dass ich nicht der einzige bin, der das bis vorhin nicht wusste: tinyurl.com hat auch eine API. Die ist zwar unglaublich simpel, aber das ist doch auch mal schön. $tinyURL = file_get_contents( &#039;http://tinyurl.com/api-create.php?url=&#039;.$tooLongURL ); und vice versa (hackish): function reverse_tinyurl($url){ // Resolves a TinyURL.com encoded url to it&#039;s source. $url = explode(&#039;.com/&#039;, &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2009/10/15/tiny-urls-mit-php-und-de-tinyurl-api/" class="more-link">Continue reading<span class="screen-reader-text"> "Tiny URLs mit PHP und der tinyurl API"</span></a></p>
The post <a href="https://nerdpress.org/2009/10/15/tiny-urls-mit-php-und-de-tinyurl-api/">Tiny URLs mit PHP und der tinyurl API</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>für den Fall dass ich nicht der einzige bin, der das bis vorhin nicht wusste:</p>
<p><a href="http://tinyurl.com/">tinyurl.com</a> hat auch eine API.<br />
Die ist zwar unglaublich simpel, aber das ist doch auch mal schön.</p>
<pre class="brush: php; title: ; notranslate">
$tinyURL =  file_get_contents( &#039;http://tinyurl.com/api-create.php?url=&#039;.$tooLongURL );
</pre>
<p>und vice versa (hackish):</p>
<pre class="brush: php; title: ; notranslate">
function reverse_tinyurl($url){
            // Resolves a TinyURL.com encoded url to it&#039;s source.
            $url = explode(&#039;.com/&#039;, $url);
            $url = &#039;http://preview.tinyurl.com/&#039;.$url&#x5B;1];
            $preview = file_get_contents($url);
            preg_match(&#039;/redirecturl&quot; href=&quot;(.*)&quot;&gt;/&#039;, $preview, $matches);
            return $matches&#x5B;1];
        }
</pre>
<p><span id="more-409"></span></p>
<p>und noch die CURL variante von ersterem (via <a href="http://davidwalsh.name">davidwalsh</a>)</p>
<pre class="brush: php; title: ; notranslate">

//gets the data from a URL  
function get_tiny_url($url)  
{  
	$ch = curl_init();  
	$timeout = 5;  
	curl_setopt($ch,CURLOPT_URL,&#039;http://tinyurl.com/api-create.php?url=&#039;.$url);  
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);  
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);  
	$data = curl_exec($ch);  
	curl_close($ch);  
	return $data;  
}
</pre>The post <a href="https://nerdpress.org/2009/10/15/tiny-urls-mit-php-und-de-tinyurl-api/">Tiny URLs mit PHP und der tinyurl API</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2009/10/15/tiny-urls-mit-php-und-de-tinyurl-api/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Feednapi Media Browser</title>
		<link>https://nerdpress.org/2009/10/14/feednapi/</link>
					<comments>https://nerdpress.org/2009/10/14/feednapi/#comments</comments>
		
		<dc:creator><![CDATA[Ivo Bathke]]></dc:creator>
		<pubDate>Wed, 14 Oct 2009 14:03:46 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[Smugmug]]></category>
		<category><![CDATA[Vimeo]]></category>
		<category><![CDATA[Youtube]]></category>
		<category><![CDATA[Zenfolio]]></category>
		<category><![CDATA[Zooomr]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=402</guid>

					<description><![CDATA[<p>So mal ein bißchen Werbung in eigener Sache: Mein Freizeit Projekt ist online: http://feednapi.net Was macht es? Es durchsucht verschiedene (viele) MedienSites nach bestimmten Keywords und stellt die neuesten Ergebnisse (schön) dar. Wie gehts? Es benutzt ganz brav die APIs der Sites. Was soll das? Das Web ist vielfältig und die Resourcen zu gewissen Interessengebiete &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2009/10/14/feednapi/" class="more-link">Continue reading<span class="screen-reader-text"> "Feednapi Media Browser"</span></a></p>
The post <a href="https://nerdpress.org/2009/10/14/feednapi/">Feednapi Media Browser</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>So mal ein bißchen Werbung in eigener Sache:<br />
Mein Freizeit Projekt ist online:</p>
<p><strong><a href="http://feednapi.net" target="_blank">http://feednapi.net</a></strong></p>
<p><strong>Was macht es?</strong><br />
Es durchsucht verschiedene (viele) MedienSites nach bestimmten Keywords und stellt die neuesten Ergebnisse (schön) dar.</p>
<p><strong>Wie gehts?</strong><br />
Es benutzt ganz brav die APIs der Sites.<span id="more-402"></span></p>
<p><strong>Was soll das?</strong><br />
Das Web ist vielfältig und die Resourcen zu gewissen Interessengebiete sind verteilt. Das zu bündeln und eine Übersicht zu behalten war die Motivation.<br />
ZB sind viele Flickr Nutzer nach Änderungen in den AGBs bzw nach restriktiverer Zensur zu Zooomr gewechselt.<br />
Sucht man nun bei Flickr nach irgendeinem Motiv, würde man Medien dieser Nutzer nicht mehr finden. Das wäre schade. Bei Feednapi findet man beide.</p>
<p><strong>Wann soll ich es benutzen?</strong><br />
Immer! Naja, Sinn macht es besonders dann, wenn man nach einem Event die neuesten Uploads im Blick haben will. Oder man Fan einer Band ist und man die nach den neuesten Videos sucht aber vergessen hat das diese Band vornehmlich auf Vimeo statt auf Youtube postet.<br />
Und zu guter letzt: wenn man Langeweile hat!</p>
<p><strong>Probleme?</strong><br />
Ja viele. Zum Beispiel taggen manche User ihre Inhalte etwas eigenartig, was bei den Suchergebnisse manchmal komische Dinge anzeigen läßt, die nun gar nichts mit dem Gesuchten zu tun hat.<br />
Und Feednapi ist abhängig von den Möglichkeiten die die APIs einem lassen. So hat Vimeo zB bis heute kein Sorting nach Datum implementiert und Youtube ist da auch nicht sonderlich zuverlässig.</p>
<p><strong>Wie gehts weiter?</strong><br />
Mehr Sites integrieren, Mehr Kategorien einbauen , Mehr Sorting ermöglichen. undundund<br />
Immer wenn ich mal was Zeit hab! ;)</p>
<p>Schauts euch mal an!</p>The post <a href="https://nerdpress.org/2009/10/14/feednapi/">Feednapi Media Browser</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
					<wfw:commentRss>https://nerdpress.org/2009/10/14/feednapi/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
