| | | | |
| |||||||
| Tutorials Hier findest Du Tutorials, welche nach und nach ein fertiges Script ergeben. Sehen, lernen & verstehen! |
|
| | LinkBack | Themen-Optionen | Thema bewerten |
| | |
| moderatives Dielektrikum Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Inspiriert von Zerglings letzter Frage zu Bitmasken, möchte ich ein paar Grundlagen zu Dualzahlen und deren Verwendung als Flag zum Besten geben. Die meisten werden bei der Arbeit mit PHP schon die Bekanntschaft mit Flags gemacht haben. Sie werden oft benutzt, um das Verhalten von Funktionen mit hinter aussagekräftigen Konstantennamen definierten Werten zu beeinflussen. Dabei können meist mehrere Konstanten durch | (Pipe) kombiniert werden. Hinter diesem Verfahren steckt ein einfaches Prinzip: die Stelle, an der bei Funktionsaufruf keine, eine oder eine Anzahl mit Pipe verknüpfter Konstanten angegeben wird, erwartet eigentlich einen ganz normalen Funktionsparameter, speziell einen Binärwert. Die zugehörigen Konstanten werden ebenfalls als Binärzahlen definiert, jede entspricht dabei einem anderen ganzzahligen Exponenten (Das kann man gut sehen, wenn man sich die Konstanten einer beliebigen Funktion mit Flags einfach mal ausgeben läßt). Das Pipe Symbol ist dann schlichtweg der Bit-Operator für 'ODER'. Ein Beispiel: Wir haben eine Funktion, die verschiedene Arbeitsweisen bietet, gesteuert von 4 Konstanten oder deren Kombination. Wir nennen diese Zustände mal AA, BB, CC und DD. Jeder dieser Zustände wird nun als Konstante mit einer Zahl aus dem Binärsystem belegt: Code: AA - 1 BB - 2 CC - 4 DD - 8 Code: AA - binär 0001 = 2 hoch 0 BB - binär 0010 = 2 hoch 1 CC - binär 0100 = 2 hoch 2 DD - binär 1000 = 2 hoch 3 Binär 1010 wäre demzufolge die Schreibweise für eine Kombination aus den Zuständen BB und DD. Kurzer Ausflug in die interne Darstellung in php:
1. Verwendung als Flag (Zustandsangabe) Nehmen wir an, unsere Zustände AA bis DD sollen einer Funktion bestimmte Verhaltensweisen signalisieren. Wir definieren uns zunächst, wie oben bereits beschrieben unsere Binärwerte als Konstante. PHP-Code: PHP-Code: Code: AACC Code: 0001 (AA)
ODER 0100 (CC)
----
0101
Innerhalb der Funktion gilt es nun, die Flags wieder voneinander zu trennen. Wir wollen dies mit einem weiteren Bit-Operator, dem UND tun. UND tut genau das Gegenteil von ODER: es setzt jede Dualstelle auf 0, an der in mindestens einem der Operanden auch eine 0 steht. Da die Konstanten global und damit auch in der Funktion verfügbar sind, prüfen wir nun alle 4 Flags auf Gesetztsein des entsprechenden Bits, in dem wir sie mit dem Inhalt von $flags UND-verknüpfen. Exemplarisch für AA und BB: Code: 0101 ($flags)
UND 0001 (AA)
----
0001
0101 ($flags)
UND 0010 (BB)
----
0000
In unserer Funktion werden alle 4 Zustände geprüft und bei Übereinstimmung mit der Konstante der gesetzte Zustand durch Ausgabe des Konstantennamens signalisiert. Bei einer 'echten' Funktion könnten jetzt hier bestimmte Fälle abgearbeitet werden, wobei meist weitere Parametervariablen verarbeitet werden würden. 2. Verwendung gegenteiliger Flags php Funktionen wie bspw. preg_match_all() verwenden auch durchaus Flags, die miteinander kombiniert gegenteilige Bedeutungen haben. Da Binärstellen prinzipbedingt nur zwei Zustände aufnehmen können, werden diese Zustände zunächst genauso angegeben wie im Vorgängerbeispiel, in der Funktion muß dann die logische Auswertung erfolgen. PHP-Code: Code: 0010 (BB)
NOT (~)
----
1101
1011 ($flags)
1101 (~ BB)
----
1001
Der Aufruf test2 (AA | BB | DD); gibt also zurück: Code: AADD Zerglings Ausgangsfrage bezog sich auf die Aufgabenstellung, eine Art Maximum der verwendeten Flags zu bestimmen, genauer gesagt, den größten innerhalb von $flags verwendeten Exponenten. Mir ist keine Möglichkeit mit Bit-Operatoren dafür bekannt. Mathematisch ausgedrückt gilt es, den 2er Logarithmus des Wertes in $flags zu bestimmen. Der ganzzahlige Teil des Ergebnisses ist unser Wert. php bietet hier eine einfachere Variante. Wir verwandeln mittels decbin() den Wert in $flags seine Stringrepräsentation, also in eine Folge von Null- und Eins-Zeichen. Von rechts beginnend steht jede Dualstelle für einen Exponenten, die erste für 2 hoch 0, die zweite für 2 hoch 1 usw. Da php intern nicht mit führenden Nullen arbeitet (wie gesagt, eigentlich ja nicht einmal mit Binärzahlen) und wir die am weitesten links stehende 1 suchen, kann das Ergebnis direkt aus der Länge der Stringrepräsentation unserer Binärzahl bestimmt werden. Wir ziehen noch 1 ab, da das erste Zeichen für 2 hoch 0 steht. Für unsere Signalfunktion (also um unserer Beispielfunktion hier irgendeinen Nutzen zu geben) verwenden wir den Exponenten, den wir erhalten haben, um mit pow() wieder eine Binärzahl zu erzeugen. Die Ausgabe erfolgt in einem Switch, da ja nur das höchstwertige gesetzte Flag gesucht war. PHP-Code: Zuletzt ein etwas konstruiertes Beispiel, das mit dem Shift Operator arbeitet. Nehmen wir an, wir wollen die übergebenen Flag-Bits nicht individuell prüfen und verarbeiten, sondern per Schleife (z.B. weil wir nicht wissen, welche numerischen Flags vorkommen können). Es wird also nötig, Bit für Bit, von 2 hoch 0 bis 2 hoch n auszulesen. Stellt man sich einen solchen Bitwert vor, wäre die naheliegendste Variante, diesen als String zu betrachten, per Schleife zeichenweise zu durchlaufen und den aktuellen numerischen Schlüssel mit der geschwungenen Klammer Syntax auszulesen. Das ist in php auch durchaus legitim, da es sich um eine schwach typisierte Sprache handelt und die Umwandlung der verschiedenen Typen im Allgemeinen automatisch erfolgt. Trotzdem möchte ich hier auch die Arbeit mit Bit-Operatoren vorstellen. Als Beispiel sollen hier einfach die Binärwerte der gesetzten Zustände ausgegeben werden. Stellt man sich jetzt 40 statt der bisher verwendeten 4 Flags vor, sieht man, dass eine Lösung wie in der ersten Funktion unglaublich viel redundaten Code erzeugen würde. Stattdessen nutzen wir eine Schleife: PHP-Code: Code: 841 Übrigens: Statt $iMax fest zu definieren, könnte auch hier wie oben die Anzahl der maximalen Dualstellen von $flags ermittelt werden. Auch wenn's zuletzt dann doch noch etwas knifflig wurde, könnt Ihr hoffentlich den einen oder anderen Punkt umsetzen, um eure Funktionen um eine paar Flag-gesteuerte Erweiterungen zu bereichern. Sinnvollerweise sollte der $flags Parameter immer mit 0 oder einem Defaultwert vorbelegt sein. Viel Spaß beim Ausprobieren, Anmerkungen und Berichtigungen sind willkommen. --n |
| | |
| | |
| PHP Code Flüsterer Registriert seit: 21.08.2005 Beiträge: 4682 PHP-Kenntnisse: Fortgeschritten | |
| | ||
| Erfahrener Benutzer Registriert seit: 21.05.2008
Beiträge: 9.937
![]() | Hast du schön gemacht ![]() Bekanntestes Beispiel hierfür sind ja die Error-Reporting-Flags in PHP, hier ein Auszug aus einer php.ini: Code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Error handling and logging ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; error_reporting is a bit-field. Or each number up to get desired error ; reporting level ; ; Examples: ; ; - Show all errors, except for notices and coding standards warnings ; ;error_reporting = E_ALL & ~E_NOTICE ; ; - Show all errors, except for notices ; ;error_reporting = E_ALL & ~E_NOTICE | E_STRICT ; ; - Show only errors ; ;error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR ; error_reporting = E_ALL Zitat:
Ist halt wirklich ne schöne Geschichte mit den Flags, weil man TRUE/FALSE Optionseinstellungen gesammelt einfach in eine Variable packen kann. Überlege man sich mal, ich müsste - bezogen auf den von nikosch verlinkten Thread von mir - für eine CSV-Spalte speichern, ob darin VARCHAR, INTEGER, DATE, etc. Werte gefunden hätte, ohne dabei auf eine Bitmaske zurückzugreifen. Das würde schnell sehr unübersichtlich werden. | |
| | |
|
| Themen-Optionen | |
| Thema bewerten | |
|
|
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| mit jQuery grosse Formulare verarbeiten | phpbeginner | HTML, Usability und Barrierefreiheit | 5 | 13.06.2008 22:58 |
| Funktions Problem mit Array | andrew22 | PHP Tipps 2007 | 11 | 03.07.2007 17:30 |
| C64 .sid sounds verarbeiten | notyyy | PHP Tipps 2007 | 2 | 22.03.2007 23:14 |
| einlesen und verarbeiten | PHP Tipps 2006 | 4 | 28.11.2006 16:04 | |
| Abfrageergebnis besser verarbeiten | HalliGalli | PHP Tipps 2006 | 2 | 17.05.2006 10:11 |
| Mehrere inserts auf einmal verarbeiten | pixelcut | PHP Tipps 2005-2 | 15 | 17.08.2005 19:15 |
| datei lesen string verarbeiten und wieder abspeichern | PHP Tipps 2005-2 | 17 | 22.06.2005 16:02 | |
| post verarbeiten | notyyy | PHP Tipps 2005-2 | 3 | 11.06.2005 12:26 |
| Phpmyadmins SQL Dump Auslesen und verarbeiten | PHP Tipps 2004 | 3 | 23.10.2004 16:51 | |
| Riesige Datei verarbeiten | Ohrwurm83 | PHP Tipps 2004 | 10 | 21.10.2004 11:41 |
| Counterdaten verarbeiten | juhuwoorps | PHP Tipps 2004 | 4 | 29.08.2004 02:09 |
| Daten von HTML-Form mit POST verarbeiten | PHP Tipps 2004 | 1 | 13.08.2004 21:35 | |
| Variable aus Eingabefeld in mein PHP-Skript verarbeiten | PHP Tipps 2004 | 5 | 26.07.2004 09:50 | |
| Daten aus Java-Script in PHP verarbeiten | PHP Tipps 2004 | 33 | 22.07.2004 09:41 | |
| array stückweise in for-schleife verarbeiten | PHP Tipps 2004 | 4 | 03.06.2004 13:51 | |
| Besucher kamen über folgende Suchanfragen bei Google auf diese Seite |
| php flags, php flag, flags php, flag php, php flags kombinieren, php flags setzen, php flag setzen, php mehrere flags, php $flag, bit shifting switches php, php funktion flag, php bitoperationen flag, php binärzahl bitweise vergleichen, php function flags, flags rechnen, php or flag, php flagg, binärsystem flags, php was sind flags, flags binär berechnen |

Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.