Ein kurzer Blick auf CSS im IE8

04. Oktober 2009

Ein kurzer Blick auf CSS im IE8 title=
Das ist bisher an mir vorbeigegangen: Auch der Internet Explorer 8 führt für seine browserspezifischen CSS Erweiterungen einen Präfix -ms ein. Damit ist die Syntax nun analog zum Mozilla -moz, Opera -o, oder Safari -webkit. Es gibt ein paar kleinere Syntaxänderungen und CSS expressions werden nicht mehr unterstützt.

Eine Liste der browserspezifischen CSS Erweiterungen für den Internet Explorer 8 findet man unter: CSS Improvements in Internet Explorer 8 und eine Kompatibilitätsliste für die unterschiedlichen IE Versionen liefert Microsoft ebenfalls. Zu den CSS Elementen, die mit dem -ms Präfix versehen wurden gehört u.a. die Eigenschaft filter. Die Syntax für dieses Element unterscheidet sich von der Syntax älterer Versionen:

/*ältere IE Versionen*/
filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
/*IE 8*/
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";

Die Präfix Elemente des IE8 sind zum guten Teil nicht neu, das Gestalten von Scrollbars, die Filter, das gab es alles bereits mit dem IE6. Auf die Implementierung von abgerundeten Ecken rounded-corners, Farbverläufen gradients oder Teiltransparenten Farbangaben rgba muß weiterhin gewartet werden. Dazu noch ein Tipp:

div {
   /* alte Browser */
   background: rgb(200, 54, 54);
   /* rgba fähige Browser */
   background: rgba(200, 54, 54, 0.5);
}
 
/* und für den ie über die Verwendung von Filter: */
<!--[if IE]>
   div  {
       background:transparent;
       filter:progid:DXImageTransform.Microsoft.gradient(
         startColorstr=#99000050,
         endColorstr=#99000050
       );
       zoom: 1;
    }
<![endif]-->

Die auf den ersten Blick merkwürdige Farbangabe #99000050 ist kein Schreibfehler, die Farbe wurde als AARRGGBB Wert notiert. Die ersten beiden Ziffern stehen für die Transparenz. Auf diesem Weg lässt sich rgba also auch für den Internet Explorer implementieren. Die Idee alternativ ein semi-transparentes PNG für diesen Effekt zu nutzen, scheitert an der Version 6 (ohne dem Einsatz von Javascript), der Filter funktioniert hingegen schon ab Version 5.

Wie bereits einleitend erwähnt: CSS expressions werden nicht mehr unterstützt. Microsoft schreibt:

While powerful, this feature was never standardized, has a high performance cost and increases the browser’s attack surface. Moreover, its main usage scenario has been to work around CSS bugs and limitations in Internet Explorer (for instance, to simulate max-width or pseudo-classes like : first-child).

Solche “wundervollen” CSS Spielereien (nochmal der IE6 und seine mangelnde PNG Unterstützung) gehören damit der Vergangenheit an – Schade nur, dass gerade die älteren ohnehin langsameren Browser diese Form der Hilfestellung weiterhin benötigen.

* html img, * html .png {
position:relative;
behavior: expression(
  (this.runtimeStyle.behavior="none") &&
   (this.pngSet ? this.pngSet=true:
    (this.nodeName == "IMG" &&
     this.src.toLowerCase().indexOf('.png') >-1 ?
     (this.runtimeStyle.backgroundImage = "none",
      this.runtimeStyle.filter = "
      progid:DXImageTransform.Microsoft.AlphaImageLoader(
       src='" + this.src + "', sizingMethod='image')",
       this.src = "transparent.gif"
     ) :
    (this.origBg = this.origBg? this.origBg :
     this.currentStyle.backgroundImage.toString().
     replace('url("','').replace('")',''),
     this.runtimeStyle.filter = "
      progid:DXImageTransform.Microsoft.AlphaImageLoader(
       src='" + this.origBg + "', sizingMethod='crop')",
       this.runtimeStyle.backgroundImage = "none"
     )
   ),
   this.pngSet=true
  )
);}

Bei generiertem Inhalt über CSS (Attribute wie content oder quotes) zieht der Internet Explorer 8 gleich, und führt die vollständige Unterstützung für generierten Inhalt nach der CSS 2.1 ein. Gleiches gilt für die Pseudo-Klassen :before, :after, :focus und :active.

Ohne Frage unterstützt der IE8 die CSS2.1 Spezifikation wesentlich besser und standardkonformer als seine Vorgänger Fassungen. Bleibt abzuwarten, ob es Microsoft gelingt das Tempo anderer Hersteller mitzugehen.

Sie können diesen Befehl jetzt nicht ausführen

08. September 2009

Sie können diesen Befehl jetzt nicht ausführen
Immer wenn es schnell gehen muß – für ein Projekt hatte ich eine stored procedure angelegt, und auf der Konsole getestet. Alles wunderbar, aber – eingebunden in ein PHP Script bricht das Ganze mit der Meldung ab: “You can’t run this command now” – ich will aber, also wo war der Fehler?

In einer gespeicherten Prozedur können ganze Abläufe von Anweisungen unter einem Namen gespeichert werden, die dann auf dem Datenbankserver zur Verfügung stehen und ausgeführt werden können. Sie ist somit ein eigenständiger Befehl, der eine Abfolge von gespeicherten Befehlen ausführt. Solche Routinen können viel Logik in die Datenbank auslagern und sind gerade bei sich ständig wiederholenden Aufgaben äußerst hilfreich.
Zurück zum Problem – die Prozedur lief auf der Konsole einwandfrei, aber über das PHP Script war nichts zu machen. Die folgenden Zeilen dienen lediglich der Veranschaulichung des Problems, mit dem eigentlichen Skript hat dieser Code-Schnipsel nichts zu tun:

$mysqli = new MySQLI('host','user','pass','db');
$result = $mysqli->query("CALL myprocedure()");
$data = $result->fetch_assoc();
$result2 = $mysqli->query("SELECT something DIFFERENT");

Ein solcher Aufruf schlägt fehl. Wahlweise man erhält den Fehler: “Lost connection to MySQL server during query“. Oder – für den Fall, dass man kein free auf das Ergebnis ($result) anwendet – eben “Commands out of sync; you can’t run this command now“. Der Grund: Eine stored procedure liefert nicht ein Ergebnis, sondern zwei – das Resultset zum einen und zum anderen eine Statusmeldung. Auch wenn es mich in dem Moment geärgert hat, der Fehler macht Sinn – sobald man sich das nächste Ergbnis abholen will, geht es nicht weiter, es hängt einfach noch ein Ergebnis in der Warteschleife (die Statusmeldung), jeder weitere REQUEST muß scheitern. Die Lösung: Anstatt $mysqli->query die Funktion $mysqli->multi_query verwenden:

$mysqli = new MySQLI('host','user','pass','db');
if($query = $mysqli->multi_query("CALL myprocedure()") {
  $result = $mysqli->use_result();
  $data = $result->fetch_assoc();
  $result->free();
  while ($mysqli->next_result()) {
    $result = $mysqli->use_result();
    if ($result instanceof mysqli_result) {
      $result->free();
   }
 }
}
$result2 = $mysqli->query("SELECT something DIFFERENT");

Diese Variante tat es für mich, und das Script lief wie gewünscht. Nachträglich bin ich dann noch auf einen Artikel gestoßen, der eben dieses “Phänomen” ausführlich beschreibt und neben der hier beschriebenen Lösung auch noch eine zweite Alternative anbietet – die Verwendung des statischen Aufrufes von MySQLI::query(). Manchmal bräuchte man halt nur die notwendige Ruhe und die richtigen Suchbegriffe.

Seite 13 von 13Anfang...910111213