PHP Konstante einsetzen

selberbauer

Captain
Registriert
Juni 2009
Beiträge
3.604
Hallo,
Ich will zum üben ein Programm schreiben, welches die Verbindung zu einen MySQL Server herstellt und Datenbanken/Tabellen prüft bzw. ggf. anlegt.

Dazu habe ich drei .php Dateien:
1. conf.php - Verbindungseinstellungen zum MySQL Server als Konstanten
2. main.php - Hauptprogramm, welches alles zusammenführt
3. check.php - Enthält Prüfungsfunktionen (Biblothek)

Allerdings habe ich immer öfter Probleme bei PHP, dass sich Strings, Variablen usw. überschneiden aufgrund recht unterschiedlicher Funktionen.

Was muss ich ändern damit diese Programm klappt?

conf.php
PHP:
<?php

// Alle Fehler anzeigen
error_reporting(E_ALL);

// Verbindungsdaten
define('MYSQL_HOST', 'localhost');
define('MYSQL_USER', 'root');
define('MYSQL_PASSWORD', '****');
define('MYSQL_DATABASE', 'Kontakte');

?>

check.php
PHP:
<?php

// Prüft ob zu verbindende Datenbank vorhanden ist oder ggf. angelegt werden muss
function check_db() {
	if(mysql_select_db(MYSQL_DATABASE) == False) {
		mysql_error();
		mysql_query("CREATE DATABASE" . MYSQL_DATABASE); // MySQL Anweisung muss in Anführungszeichen, Konstante allerdings auch
		check_db() OR die(mysql_error());
	}
}

?>

main.php
PHP:
<?php

// Verbindungsdaten einlesen
require_once('conf.php');
$db_link = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD);
// Biblotheken einlesen
require('check.php');

check_db();

echo 'Scheinbar erfolgreich';
?>
 
Zuletzt bearbeitet:
Beim Überfliegen ist mir mindestens das hier aufgefallen:

mysql_query("CREATE DATABASE " . MYSQL_DATABASE);
 
Jep, das ist die Lösung. :) Konstanten immer ohne Anführungszeichen und ohne $ - also auch nicht wie normale Variablen aufrufen.
 
Wirklich schade dass PHP evaluierende Strings besitzt... Und dass Tutorials dies auch noch aufgreifen ist umso schlimmer. :(

Mit '' wär dir das nicht passiert.
 
Aus irgendeinem Grund geht das immernoch nicht, der Webserver lädt ewig und gibt dann einen HTTP Fehler 500 aus.
Kann es sein, dass sich die Funktion rekursiv ewig aufruft anstatt auszubrechen?
 
check.php zeile 8.
dein select_db schlägt fehl, also ruft er sich wieder selber auf.

aber wie wäre es mit code selber lesen?

p.s.
false schreibt man klein.
 
Zuletzt bearbeitet:
aber wie wäre es mit code selber lesen?
Aus irgendeinem Grund geht das immernoch nicht, der Webserver lädt ewig und gibt dann einen HTTP Fehler 500 aus.
Kann es sein, dass sich die Funktion rekursiv ewig aufruft anstatt auszubrechen?
Fällt was auf?

Wie löse ich das Problem, wenn OR nicht funktioniert?

PS:
Habe jetzt Zeile 8 aus check.php gelöscht.
1.) Warum meldet mysql_select_db ein false und wird deswegen nochmal aufgerufen, wenn doch alles klappen sollte?
2.) Die erstellte Datenbank heisst jetzt nicht "Kontakte", sondern MYSQL_DATABASE. Wie setze ich eine Konstante also richtig ein, sodass sie nicht mit einem String verwechselt wird?

Gruß
 
Zuletzt bearbeitet:
selberbauer schrieb:
Wie löse ich das Problem, wenn OR nicht funktioniert?
PHP:
function check_db() { return mysql_select_db( MYSQL_DATABASE ); }

if( !check_db() ) die( mysql_error() );
 
Danke ;)
Jetzt muss nur noch die Konstante richtig deklariert werden, momentan funktioniert das nicht ganz und er versucht sich mit der Datenbank "MYSQL_DATABASE" zu verbinden.

@Yuuri
Du scheinst PHP professionell zu machen?
Arbeitest du da auch mit Konstanten oder bevorzugst du einen anderen Weg?

Gruß
 
Mein Ratschlag:
Setz dich mal 5 Minuten an die frische Luft, komm dann wieder und schau dir deine Logik an, ob sie überhaupt so funktionieren könnte.

Wieso der select_db fehlschlägt, sagt dir mysql_error(); in Zeile 6. Wenn man jetzt auch noch sich ein wenig bemüht und nachliest sieht man: mysql_error() returns a string containing.... http://de2.php.net/mysql_error
Also wenn du es angezeigt haben willst muss ein echo davor: echo mysql_error();

Und wieso überhaupt Konstanten? Mach dir ne config.inc.php, da kommt rein $_CONFIG['mysql_host'] = 'localhost'; und später greifst du dann nur auf den Array zu per mysql_select_db($_CONFIG['mysql_database']);. Die Toplösung wäre eine eigenen config-Class mit settern und gettern, wobei das bei so einer Kleinigkeit way over the top wäre.
 
selberbauer schrieb:
Du scheinst PHP professionell zu machen?
Was meinst du mit professionell? Ich programmier einfach, u.a. auch meine eigenen Seiten, bin aber nirgendwo dafür angestellt.
selberbauer schrieb:
Arbeitest du da auch mit Konstanten oder bevorzugst du einen anderen Weg?
Ich mag Konstanten da, wo sie sinnvoll sind. Unter anderem eben bei solchen Sachen, die aus der Config oder irgendwoher gelesen werden. Kommt ganz auf die Vorliebe eines Jeden und die Verwendung an. Und da sich Login-Daten bei mir im Script eh nie ändern, definier ich solches als Konstante.
thes33k schrieb:
Setz dich mal 5 Minuten an die frische Luft, komm dann wieder und schau dir deine Logik an, ob sie überhaupt so funktionieren könnte.
Raucherpause, Runde laufen, kurz was anderes machen, ... Hilft wirklich Wunder. ;)
thes33k schrieb:
Und wieso überhaupt Konstanten? Mach dir ne config.inc.php, da kommt rein $_CONFIG['mysql_host'] = 'localhost'; und später greifst du dann nur auf den Array zu per mysql_select_db($_CONFIG['mysql_database']);.
Ver(sch)wendung von Arrays ist auch nicht das Wahre. Die Daten ändern sich innerhalb des Scripts doch eh nicht, wozu also variabel gestalten? Konstanten funktionieren genauso und wie oben erwähnt, mag ich lieber Konstanten setzen, wo Sachen konstant sind und Variablen wo sich Sachen verändern oder dynamisch generiert werden. Heißt ja nicht umsonst Konstante und Variable. ;) Den *.inc.php-Weg hasse ich auch wie die Pest, da alles irgendwo steht, aber nirgendwo zentral, übersichtlich und schnell zugreifbar.
thes33k schrieb:
Die Toplösung wäre eine eigenen config-Class mit settern und gettern, wobei das bei so einer Kleinigkeit way over the top wäre.
OOP macht selbst in PHP wirklich Spaß. Bastel momentan auch noch an einem Script, was komplett objektorientiert arbeitet.
 
Naja, Konstanten in PHP sind etwas "speziell". Ausserdem stehen die schlussendlich auch wieder in einem Array/Hash.
 
Und wieso überhaupt Konstanten? Mach dir ne config.inc.php, da kommt rein $_CONFIG['mysql_host'] = 'localhost'; und später greifst du dann nur auf den Array zu per mysql_select_db($_CONFIG['mysql_database']);. Die Toplösung wäre eine eigenen config-Class mit settern und gettern, wobei das bei so einer Kleinigkeit way over the top wäre.
Gute Idee, werde ich so umsetzen ;)

Was meinst du mit professionell? Ich programmier einfach, u.a. auch meine eigenen Seiten, bin aber nirgendwo dafür angestellt.
Habe ich jetzt aus der objektorientierten Darstellung abgeleitet (stand zumindest so im Tutorial :D

er(sch)wendung von Arrays ist auch nicht das Wahre. Die Daten ändern sich innerhalb des Scripts doch eh nicht, wozu also variabel gestalten? Konstanten funktionieren genauso und wie oben erwähnt, mag ich lieber Konstanten setzen, wo Sachen konstant sind und Variablen wo sich Sachen verändern oder dynamisch generiert werden. Heißt ja nicht umsonst Konstante und Variable. Den *.inc.php-Weg hasse ich auch wie die Pest, da alles irgendwo steht, aber nirgendwo zentral, übersichtlich und schnell zugreifbar.
An sich einleuchtend, aber dadurch, dass man bzw. ich relativ schnell Fehler mache durch fehlende deklarationen wie "$", finde ich variablen als Anfänger einfacher. Konstanten sind bei mathematischen Zahlen sehr gut, bei Login Daten wegen dem Deklarationsproblem immernoch problematisch, soweit ich das beurteilen könnte....
Ergänzung ()

Nebenbei gibt es zufällig ein Tutorial, welches von vorne rein die OOP verwendet, auch bei einfachen Programmen und auf einen guten Programmierstyle achtet?

Momentan benutze ich folgendes Tutorial: http://www.php-kurs.com/mysql-datenbank-anlegen.htm
 
bu1137 schrieb:
Naja, Konstanten in PHP sind etwas "speziell".
Inwiefern sind Konstanten speziell?
bu1137 schrieb:
Ausserdem stehen die schlussendlich auch wieder in einem Array/Hash.
Schlussendlich landet alles in einem Array, egal welche Variable, Konstante, String, Nummer oder sonstwas. Interessiert mich aber nicht, denn Konstanten werden als Konstanten definiert und sind ab da an nicht mehr veränderbar (weder absichtlich noch unabsichtlich). Überschreiben kann man sie ebenso nicht aus Versehen.

Aber wo werden Konstanten in einem Array hinterlegt? Außer über get_defined_constants() komme ich nirgendwo an eine Übersicht o.ä. Als superglobale Variable sind Konstanten auch nicht hinterlegt. Dass PHP alle Konstanten intern als Array anlegt ist doch nur logisch, da sie sonst nie wieder auffindbar wären. So entstehen nur Speicherlecks.
 
Yuuri schrieb:
Ich mag Konstanten da, wo sie sinnvoll sind. Unter anderem eben bei solchen Sachen, die aus der Config oder irgendwoher gelesen werden. Kommt ganz auf die Vorliebe eines Jeden und die Verwendung an. Und da sich Login-Daten bei mir im Script eh nie ändern, definier ich solches als Konstante.
Konstanten werden spätestens dann hässlich, wenn dein Produktions-System nicht deinem Dev-System entspricht :) Insgesamt hast du jedoch recht, dass man immer das für den Sinn Geschaffene nutzen sollte. Hier wirken Konstanten auch die richtige Wahl, aber der Umgang mit ihnen ist in PHP nunmal... wieso sollte ich es nutzen, wenn es die Sache eigentlich nur verkompliziert. Das Ursprungsproblem mit überschneidenden Variablen zeugt ja schon nicht gerade von "ich weiß was ich da tue".

Ver(sch)wendung von Arrays ist auch nicht das Wahre. Die Daten ändern sich innerhalb des Scripts doch eh nicht, wozu also variabel gestalten? Konstanten funktionieren genauso und wie oben erwähnt, mag ich lieber Konstanten setzen, wo Sachen konstant sind und Variablen wo sich Sachen verändern oder dynamisch generiert werden. Heißt ja nicht umsonst Konstante und Variable. ;) Den *.inc.php-Weg hasse ich auch wie die Pest, da alles irgendwo steht, aber nirgendwo zentral, übersichtlich und schnell zugreifbar.
bu1137 hats schon gesagt, auch Konstanten landen intern in nem Array.
Bezüglich .inc.php. Das ist ja nur ein "pattern", das den Zusammenhang verdeutlichen soll. Übersichtlicher als drölf .php Klassen unstrukturiert ist es alle mal. Ich finde auch gerade, dass es keinen zentralen allwissenden Punkt gibt, sehr gut. Aber das ist halt je nachdem wie sehr man Abstraktion mag oder nicht.

OOP macht selbst in PHP wirklich Spaß. Bastel momentan auch noch an einem Script, was komplett objektorientiert arbeitet.
Solang man OOP dann nutzt, wenn es Sinn macht, ja. Dann macht es Spaß. Aber für ein simples Script wie dieses hier ist es einfach nur unnützer overhead.

p.s.
Ergänzung vom 17.11.2011 19:05 Uhr: Nebenbei gibt es zufällig ein Tutorial, welches von vorne rein die OOP verwendet, auch bei einfachen Programmen und auf einen guten Programmierstyle achtet?
Ich würde behaupten, dass sowas schwerer zu finden sein wird, weil php so "einfach" ist, dass es extrem viele "können". Daraus ergibt sich ne riesige Masse an unnützen Tutorials, die schlechten Stil vermitteln. Design Patterns werden da ganz gerne hochgelobt, wo sie nicht passen. Man sollte semantisch programmieren, also das einsetzen, was für seinen Zweck geschaffen wurde. Bestes Beispiel dafür ist, dass es unzählig viele Menschen gibt, die div Positioning in HTML hochloben und für alles verwenden wollen. Wenn ich allerdings ne Tabelle anzeigen will, dann ist auch ne table der richtige Weg und nicht unzählig viele divs, die ich positionieren muss.
Mein Tip zum Lernen von php: php.net Dokumentation stets nutzen, nicht einfach copy&pasten, sondern wirklich Zeile per Zeile verstehen, was da passiert und wenn man noch was zu Lesen möchte:
http://www.amazon.de/PHP-Design-Pat...864X/ref=sr_1_1?ie=UTF8&qid=1321553837&sr=8-1
Da werden viele verschiedene Design Patterns vorgestellt, die so gang und gäbe sind.
Und wenn du mit OOP ansich arbeiten möchtest, unbedingt ne IDE wie eclipse mit php developer tools nutzen.
 
Zuletzt bearbeitet:
selberbauer schrieb:
An sich einleuchtend, aber dadurch, dass man bzw. ich relativ schnell Fehler mache durch fehlende deklarationen wie "$", finde ich variablen als Anfänger einfacher. Konstanten sind bei mathematischen Zahlen sehr gut, bei Login Daten wegen dem Deklarationsproblem immernoch problematisch, soweit ich das beurteilen könnte....
Wenn du Konstanten falsch schreibst, also nicht darauf zugreifen kannst, wird die eine Notice um die Ohren geworfen (wenn du error_reporting( E_ALL ) verwendest). Genauso verhält es sich auch bei nicht existierenden Variablen oder Arrays mit nicht existierendem Index. Konstanten heißen übrigens Konstanten, da man dessen Wert nicht mehr verändern darf/kann. Und wenn Login-Daten geändert werden und dadurch ein Zugriff nicht stattfinden kann, hast du Pech gehabt und evtl. suchst du dich dumm und dusslich, da evtl. einige Scripte Seiteneffekte hervorbringen. Mit dem Einsatz von Konstanten beugst du dem schon mal konkret vor, da dieser nur ein mal definiert werden können.

Merke: Konstanten sind da sinnvoll, wo Werte nur ein Mal definiert werden müssen.

Auch die Performance kann übrigens dadurch verbessert werden (bspw. kann der C# JIT so fixe Werte einsetzen, anstatt immer nach dem Wert einer Variablen zu fragen).

An deiner Stelle würde ich sofort auf eine IDE umsteigen (egal ob Anfänger oder nicht), denn diese nimmt dem Programmierer immens viel Arbeit ab (definierte Konstanten, Variablen, Typen von Variablen, PhpDoc, Funktionen-, Klassen-, Methodenübersichten, ...). Natürlich wird man von Anfang an mit Funktionen, aber du kannst doch nur das Nutzen, womit du dich momentan auskennst. In den Rest kommst du so oder so später von allein rein. Mit IDEs treten auch weniger Fehler ein, da man immer definierte Variablen einsehen kann und ggf. die erweiterte Funktionalität dieser erfährt (insofern man seinen Code dokumentiert).

Ich persönlich nutze Nusphere PhpEd. Eine gute Alternative ist aber auch Netbeans.
thes33k schrieb:
Hier wirken Konstanten auch die richtige Wahl, aber der Umgang mit ihnen ist in PHP nunmal...
Wieso ist der Umgang schlecht? Es ist doch nichts anderes als ein const <typ> abc = 3.14159; (bzw. #define xyz wenn man den Scope betrachtet), also müsste es in allen anderen Sprachen auch schlecht sein.
thes33k schrieb:
bu1137 hats schon gesagt, auch Konstanten landen intern in nem Array.
Was intern geschieht ist mir persönlich egal, denn ich arbeite mit PHP und nicht dessen Internem. ;) Aber wo landen Konstanten in einem Array, sodass ich über $CONSTANTS['MEINE_DEFINIERTE_KONSTANTE'] zugreifen kann (außer der Übersicht von get_defined_constants())?

Wie schon geschrieben: Irgendwo landet alles in einem Array und spätestens wenn es im RAM liegt, liegt es in einem Array.
 
Yuuri schrieb:
Wieso ist der Umgang schlecht? Es ist doch nichts anderes als ein const <typ> abc = 3.14159; (bzw. #define xyz wenn man den Scope betrachtet), also müsste es in allen anderen Sprachen auch schlecht sein.
Das Problem in PHP ist: Konstanten verzichten auf den Identifier für Strukturmerkmale ($). Während ich in C sowieso für jede var seinen type etc. kennen muss, geht php damit lapidar um. Das schärft halt das Verständnis fürs Programmieren und führt nicht so schnell zu Fehler ("oh, ausversehen nen $ vor ne Konstante geschrieben"). Da gibts ne ganze Reihe an Dingen, auf die man aufpassen muss, die zum Teil auch in den Kommentaren der Dokumentation aufgegriffen werden.
Dazu kommen halt Alltagsprobleme, dass eine Konstante vielleicht doch lieber eine var sein sollte, etc.
Konstanten sind in php einfach inkonsistent im Vergleich zu anderen Strukturen implementiert. Das merkt man aber auch an allen Ecken und Enden insgesamt bei php (z.B. verdrehte Übergabeparameter-Reihenfolgen bei ähnlichen Funktionen oder die typischen Probleme aus dem Mangel an Typensicherheit).

Was intern geschieht ist mir persönlich egal, denn ich arbeite mit PHP und nicht dessen Internem. ;) Aber wo landen Konstanten in einem Array, sodass ich über $CONSTANTS['MEINE_DEFINIERTE_KONSTANTE'] zugreifen kann (außer der Übersicht von get_defined_constants())?

Wie schon geschrieben: Irgendwo landet alles in einem Array und spätestens wenn es im RAM liegt, liegt es in einem Array.
Richtig, deshalb ist es auch fast egal, ob du nun nen eigenen Array anlegst, oder Konstanten verwendest. Das eine Array wird nur als schreibgeschützt "geflagt".
Genau aus dem gleichen Grund sind diese Streiterein über for/foreach/while auch Unsinn, weil es intern sowieso immer zu ner for auf nem array mit einer bekannten Länge wird.
 
Du kreidest hier gerade Sachen an, die es eigentlich in jeder Programmiersprache so gibt. Beziehungsweise dein letzter Absatz (des ersten Abschnitts) geht auf die Probleme von PHP und nicht von der auf Konstanten ein.

Dass ein Unterschied zwischen Variable und Konstante gemacht wird, sehe ich als positiv an, denn somit wird gleich klar, was eine Variable und was eine Konstante ist. In C bspw. gibt es die Konvention Konstanten groß zu schreiben. In PHP ist es halt das Großschreiben (was automatisch gemacht wird bei der Deklaration), sowie der Zugriff ohne $-Zeichen. Ist halt anders, aber deswegen doch nicht schlecht. Dass PHP keine Typsicherheit kennt, kannst du nicht erneut auf Konstanten festsetzen, denn dann könnte ich das auch für Variablen tun. Ist aber ein "Problem" von PHP. Das kann aber auch von Vorteil sein und dank Überprüfungen auf Typengleichheit (===, !=== bspw.) kann man vieles umgehen. Natürlich ist es manchmal umständlich, aber wenn man allgemeingültige Funktionen/Wrapper schreibt und wirklich auf einen leeren String oder eine Int Null überprüfen will, kann man dies auch. Man muss nur wollen. Wenn du Konstanten durch Variablen ersetzen willst, funktioniert das einfach, indem du ein $ davorsetzt. In C bspw. würdest du die Variable einfach lokal deklarieren. Weiter gedacht (Konstante mit #define) müsstest du den kompletten Code umschreiben, damit aus einer Konstante eine Variable wird. Mit PHP hast du das Problem hier nicht. Auch ist es eher ein allgemeingültiges Problem und nicht einer Sprache anzukreiden.
thes33k schrieb:
Richtig, deshalb ist es auch fast egal, ob du nun nen eigenen Array anlegst, oder Konstanten verwendest. Das eine Array wird nur als schreibgeschützt "geflagt".
Und genau das ist doch der entscheidende Punkt, zusätzlich zu dem Punkt, dass du gar nicht die Möglichkeit besitzt, eine Konstante/Variable einfach so zu überschreiben. Schlimm sind Keywords wie global $xyz, wodurch mir nichts dir nichts Seiteneffekte entstehen können und du dich nach dem Fehler tot suchst. Schön dass es die Möglichkeit gibt (für erfahrene Nutzer, wenn überhaupt), aber meistens wird sie doch nur zweckfrei verwendet, nur um etwaige Komplikationen umgehen zu können. Mit Konstanten wär dir das nicht passiert.

Weiter ist es eben nicht egal, denn der Zugriff ist doch genau das Entscheidende. Erklär einem C-/Java-/Delphi-/...-Programmierer mal, dass er doch auf Variablen zurückgreifen soll, denn sie werden doch eh nur irgendwie oder irgendwann als Array gespeichert. Wie der PC/Compiler es intern umstrukturiert ist doch komplett egal, logisch und semantisch betrachtet ist es eben nicht egal.
thes33k schrieb:
Genau aus dem gleichen Grund sind diese Streiterein über for/foreach/while auch Unsinn, weil es intern sowieso immer zu ner for auf nem array mit einer bekannten Länge wird.
Es ergibt aber semantischen und sogar einfacher zu verstehenden Code.

Anstatt
Code:
foreach( $Daten as $Index => $Wert ) { ... }
will ich nicht jedes Mal
Code:
$Indizes = array_keys( $Daten );
$Werte = array_values( $Wert );
for( $i = 0; $i < sizeof( $Indizes ) && $i < sizeof( $Werte ); ++$i )
{
  $Index = $Indizes[$i];
  $Wert = $Werte[$i];

  ...
}
schreiben. Es ist eben nicht das Gleiche, ob nun for oder foreach.

Was an while auszusetzen sein soll, verstehe ich aber auch nicht. Ich schreibe lieber kurz
Code:
while( $a != $b ) { ... }
anstatt
Code:
for(; $a != $b;) { ... }
Erklär bspw. einem Anfänger mal, was for(;$x;) macht. while($x) versteht er sofort.

Aber zuletzt: Eine Variable, dessen Wert sich nicht verändert ist eine Konstante [1], welche du demzufolge einfach als Solche definieren kannst. Weshalb so plötzlich eine Konstante zu einer Variable werden soll erschließt sich mir nicht. Ich wüsste kein Anwendungsbeispiel, wo dies passieren könnte.

[1] Was übrigens auch der C#-/Java-JIT erkennt und dies zur Laufzeit ersetzt, damit die Ausführung schneller stattfindet.
 
Wäre es eigentlich auch möglich, C++ als Template-Sprache zu verwenden oder ist der Aufwand zu hoch?

Müsste es nicht reichen, eine MySQL-, HTML-lib zu integrieren und ein passendes Apache Modul zu benutzen.

Den C++ ist wesentlich genauer und lässt keine Fehler zu.
 
selberbauer schrieb:
Wäre es eigentlich auch möglich, C++ als Template-Sprache zu verwenden oder ist der Aufwand zu hoch?
Du kannst alles wenn du willst, aber ich glaube weniger, dass du für jede Art von Server einen entsprechenden Build erstellen willst. Ist ja nicht so, dass es nur Windows und Linux auf Servern gibt. Weiterhin würdest du wohl eher nur die Syntax von C++ übernehmen wollen (denke ich mal), also schreib dir deinen eigenen Parser, der bspw. den Code in PHP überführt. Später kannst du ja deinen komplett eigenen Parser schreiben, womit du das PHP Problem umgehen könntest. Ich denke aber jetzt schon, dass du sehr schnell daran scheitern wirst, einfach weil das Thema zu komplex und kompliziert ist.

Man sieht doch allein, dass man ASP.NET kaum auf Webhostern findet, weder Java, noch Python, noch sonstige, evtl. exotische Sprachen sind lauffähig.
 
Zurück
Oben