Delphi-PRAXiS
Seite 8 von 8   « Erste     678   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   PHP - sind hier "Sicherheitsexperten" an Board? (https://www.delphipraxis.net/152621-php-sind-hier-sicherheitsexperten-board.html)

himitsu 8. Aug 2010 21:35

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
Wo jetzt erstmal wieder alles läuft und zusätzlich noch die mysql- und templatte-klassen fertig sind (und hoffentlich auch alles läuft)
und bevor ich mich ans Rechte und Benutzer-System wende, wollte ich mal wieder etwas fragen:


Und zwar hab ich von vielen Klassen deren Namen direkt für die Anbindung an die DB genutzt.
Leider kann man ja nicht von einer Klasse den Namen auslesen.
Der PHP-Parser hat was dagegen, wenn man den Klassennamen direkt als "String" verwenden will, aber diesen nicht schon als String in den Quelltext reinschreibt.
PHP-Quellcode:
class MeineKlasse {
}

echo MeineKlasse;
if (is_subclass_of($obj, MeineKlasse)) ...
Hier meckert er jedenfalls rum.
Zitat:

Notice: Use of undefined constant MeineKlasse - assumed 'MeineKlasse' in ... on line 6
Notice: Use of undefined constant MeineKlasse - assumed 'MeineKlasse' in ... on line 7
Und nein, den Namen als String will ich nicht angeben, denn da fallen Verschreiber nicht immer gleich auf.
Wenn man den Klassennamen nutzen würde, dann könnte eine Meldung ala "unbekannte Klasse" erzeugt werden.

nun war ich erstmal auf diese saublöde Idee (und verwende sie schon eine kleine Weile)
PHP-Quellcode:
class test {
  static function Name()
  {
    return get_called_class();
  }
}

echo test::Name();
leider finde ich das etwas umständlich,
aber immerhin kommt bei einem Verschreiber etwas wie "... besitzt diese Methode nicht" :-D

Nun bin ich vor ein paar Minuten auf diese noch krankere Idee gekommen, hab's ausprobiert und erschreckender Weise scheint es zu funktionieren. :shock:
(also, es geht um die Konstante ... das __toString ist nur bei dem Test mit drin)
PHP-Quellcode:
class test {
  function __toString()
  {
    return get_called_class();
  }
}
define('test', 'test');

$test = new test;
if ($test instanceof test) echo 'yes';

echo test;
echo $test;
Wie gesagt, in diesem kleinen Test funktioniert es, auch wenn ich nicht verstehe, wie PHP nun zwischen der Konstannte und der Klasse unterscheidet. :gruebel:


Spricht jetzt irgendwas gegen dieses Vorgehen?
(natürlich würde ich mir diese Konstanten automatisch generieren lassen, um da ebenfalls Verscheiber zu unterbinden)

alcaeus 8. Aug 2010 21:49

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
Zitat:

Zitat von himitsu (Beitrag 1040298)
Leider kann man ja nicht von einer Klasse den Namen auslesen.

Falsch. Ich erwaehne hier einfach mal get_class(). Alternativ gibts auch instanceof.
Zitat:

Zitat von himitsu (Beitrag 1040298)
Der PHP-Parser hat was dagegen, wenn man den Klassennamen direkt als "String" verwenden will, aber diesen nicht schon als String in den Quelltext reinschreibt.

Aus gutem Grund. Das was du im angegebenen Code machst ist eine Konstante namens "MeineKlasse" zu verwenden. Es ist einfach: alles was keine Zahl, kein String-Literal, keine Variable ist in diesem Kontext eine Konstante. Insofern hat der Parser auch recht wenn er dir den Code mit der Notice um die Ohren wirft. Das ist wirklich beschissener Code den du da geschrieben hast.

Zitat:

Zitat von himitsu (Beitrag 1040298)
Und nein, den Namen als String will ich nicht angeben, denn da fallen Verschreiber nicht immer gleich auf.
Wenn man den Klassennamen nutzen würde, dann könnte eine Meldung ala "unbekannte Klasse" erzeugt werden.

Nein, koennte nicht. Schliesslich sieht der eine Konstante die nicht existiert. Ob du MeineKlasse oder MaineKlasse schreibst ist dem Parser scheissegal - es ist immer "Use of undefined constant".

Zitat:

Zitat von himitsu (Beitrag 1040298)
nun war ich erstmal auf diese saublöde Idee (und verwende sie schon eine kleine Weile)
PHP-Quellcode:
class test {
  static function Name()
  {
    return get_called_class();
  }
}

echo test::Name();
leider finde ich das etwas umständlich,
aber immerhin kommt bei einem Verschreiber etwas wie "... besitzt diese Methode nicht" :-D

Aua. Aua. Aua. Aua.

Zitat:

Zitat von himitsu (Beitrag 1040298)
Nun bin ich vor ein paar Minuten auf diese noch krankere Idee gekommen, hab's ausprobiert und erschreckender Weise scheint es zu funktionieren. :shock:
PHP-Quellcode:
class test {
  function __toString()
  {
    return get_called_class();
  }
}
define('test', 'test');

$test = new test;
if ($test instanceof test) echo 'yes';

echo test;
echo $test;
Wie gesagt, in diesem kleinen Test funktioniert es, auch wenn ich nicht verstehe, wie PHP nun zwischen der Konstannte und der Klasse unterscheidet. :gruebel:

WTF????????
Du baust dir da ein Konstrukt hin das einfach nur noch bescheuert ist. Also wirklich bescheuert. Erstens solltest du $test mithilfe von
PHP-Quellcode:
new test();
erzeugen. Zweitens, fuehr mal den Code aus:
PHP-Quellcode:
class foo {
}
class bar {
}
define('foo', 'bar');

$test = new foo();
echo get_class($test);
So, und jetzt rate was ausgegeben wird, dann weisst du auch was Vorrang hat: Klassenname oder Konstantenname.
Wenn du direkt im Anschluss diesen Code ausfuehrst:
PHP-Quellcode:
define('foo', 'baz');
$test = new foo();
echo get_class($test);
wirst du feststellen dass beim Instanzieren von Objekten Konstantennamen nicht aufgeloest werden.

Zitat:

Zitat von himitsu (Beitrag 1040298)
Spricht jetzt irgendwas gegen dieses Vorgehen?
(natürlich würde ich mir diese Konstanten automatisch generieren lassen, um da ebenfalls Verscheiber zu unterbinden)

WTF? Du wuerdest dir automatisch Konstanten fuer Klassennamen generieren lassen weil du (verzeih mir meine Wortwahl) zu dumm bist einen Klassennamen fehlerfrei zu tippen? In dem Fall hast du ganz andere Probleme als komischen PHP-Code. Und fuers Protokoll: es sprechen zigtausende Gruende dagegen, solche komischen Eigenheiten von PHP produktiv zu nutzen. Nur weil dich die Autobahnauffahrt nicht daran hindert, gegen die Fahrtrichtung aufzufahren machst dus auch nicht um von A nach B zu kommen, oder?

Greetz
alcaeus

himitsu 8. Aug 2010 22:13

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
auf die Idee bin ich auch schon gekommen und
PHP-Quellcode:
get_class(MeineKlasse)
funktioniert nicht :zwinker:

und du weißt garnicht wie oft man sich verschreiben kann :oops:
(in Strings gibt's ja nimma 'ne Autovervollständigung)

alcaeus 9. Aug 2010 06:27

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
Zitat:

Zitat von himitsu (Beitrag 1040310)
auf die Idee bin ich auch schon gekommen und
PHP-Quellcode:
get_class(MeineKlasse)
funktioniert nicht :zwinker:

Was heisst hier "funktioniert nicht"? Versuchs mal mit
PHP-Quellcode:
get_class($meinObjekt);
Und trotzdem, was ist das Problem mit
PHP-Quellcode:
if ($meinObjekt instanceof MeineKlasse)
Greetz
alcaeus

himitsu 9. Aug 2010 06:51

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
Zitat:

Zitat von alcaeus (Beitrag 1040324)
Was heisst hier "funktioniert nicht"? Versuchs mal mit
PHP-Quellcode:
get_class($meinObjekt);
Und trotzdem, was ist das Problem mit
PHP-Quellcode:
if ($meinObjekt instanceof MeineKlasse)

In der Klasse kann man z.B. __CLASS__ als String verwenden, um den Klassennamen als Tabellen-/Feldnamen für DB-Anfragen zu nutzen.

Code:
meinObjekt             << Name von Klasse
get_class(meinObjekt)  << Name von Klasse
get_class($meinObjekt) << Name von Objekt
und es kommt natürlich der bekannte Fehler, mit der unbekannten Konstante

Tja, nun hab ich alles nach String umgewandelt und auch denganzen __CLASS__-Schrott rausgemacht,
denn es sieht sch***e aus, wenn an einer Stelle die Klasse und an anderer Stelle einen String genutzt wird.

Ich wollte einfach nur ein einheitliches Aussehn.
> in der Klasse nutzte ich __CLASS__ und self
> und z.B. im Installer wollte ich den Klassennamen direkt angeben.

öfters genutzte DB-Zugriffe und Ähnliches hab ich in Klassen zusammengefaßt
und selten/fast nie genutztes in getrennten Dateien, damit diese nicht ständig mit geladen werden müssen.

alcaeus 9. Aug 2010 18:08

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
Erklaer mal dein Problem in Ruhe von Anfang an, ohne komischen WTF-Code. Ich hab absolut nicht verstanden was du ueberhaupt willst.

Kurzer Code zur Erklaerung:
PHP-Quellcode:
class A
{
  public function foo()
  {
    echo __CLASS__;
  }
}

class B extends A
{
}

$b = new B();
Kurz zur Erklaerung: __CLASS__ ist eine magische Konstante, die immer den Namen der aktuellen Klasse beinhaltet (oder nicht definiert ist wenn du nicht im Klassen-Kontext bist).
PHP-Quellcode:
$b->foo();
Dieser Code gibt "A" aus.

get_class() ist eine Methode, der du ein Objekt, keinen String (auch nicht sowas: get_class(meineKlasse), denn das ist auch nur ein String mit Compiler-Warnung) uebergibst und die dir den Klassennamen zurueckliefert.
PHP-Quellcode:
get_class($b)
Dieser Code gibt "B" aus.

instanceof prueft ob ein Objekt ein Child einer Klasse ist.
PHP-Quellcode:
var_dump($b instanceof B);
var_dump($b instanceof A);
In diesem Fall wird zweimal true ausgegeben, denn durch die Vererbung ist $b auch eine Instanz von A.

Klar soweit?

Greetz
alcaeus

PS: __CLASS__ ist kein Schrott. Es sieht auch nicht scheisse aus wenn an einer Stelle die Klasse benutzt wird und an anderer der String. Hin und wieder brauchts das eben so. Schrott oder Scheisse ist es nur, wenn du es nicht schaffst Konzepte auseinanderzuhalten.

himitsu 9. Aug 2010 19:58

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
Was __CLASS__ ist das weiß ich schon,
aber ich wollte einfach nicht an einer Stelle eine Konstannte(Klasse) und anderer Stelle einen String für das Selbe verwenden.

PHP-Quellcode:
$Result = array();
$Database->Select(Language, array('NameID' => $NameID));
while ($Row = $Database->FetchRow())
  $Result[$Row->Lang] = $Row->Text;
return $Result;
PHP-Quellcode:
$Database->AddForeignKey(Template, 'Description', Language, 'ID');
.

Ich finde es auch praktisch, wenn die "Klasse" in der Syntaxhervorhebung des Editors anders angezeigt wird. (is irgendwie übersichtlicher, als wenn da nur irgendein String unter Anderen untergeht.


Hab aber nun allen Klassen (wo ich's genötige) eine Konstannte verpaßt, in welcher der Tabellen/Klassenname nochmal drinsteht.
PHP-Quellcode:
$Database->Select(Language::TAB, array('NameID' => $NameID));
.
Auch innerhalb der Klassen scheib ich nun dieses, obwohl da auch die magische String-Konstante __CLASS__ gegangen wäre.

Valle 9. Aug 2010 21:34

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
Also ich bin mir recht sicher, dass ich verstanden habe was du meinst. Das wird' dir aber jetzt nicht gefallen... Dein Datenbankkonzept ist in der Hinsicht einfach nicht dafür zu gebrauchen. Ich sag' dir mal wie ich (und viele andere, vielleicht auch alcaeus :-) ) das machen:
  • jede Tabelle der Datenbank entspricht einer Klasse
  • diese Klassen sind alle abgeleitet von einer gemeinsamen Tabellen-Klasse
  • diese Eltern-Klasse bietet Funktionen wie UPDATE usw. an
  • so könnte man das dann benutzen:

PHP-Quellcode:
$user = new User();
$user->passsword = md5( /*...*/ );
$user->name = $name;
$user->save();
Um SELECTs zu machen gibt es verschiedene Möglichkeiten. Darunter zum Beispiel, dass man dieser Eltern-Klasse ein Attribut (z.B. "objects") gibt, oder auch direkt einfache Methoden. So kann man das benutzen:

PHP-Quellcode:
$users = new User()->objects->all();
foreach ($users as $user) { /* ... */ }
Eine Klasse bzw. Tabelle definiert sich dann beispielsweise durch sowas hier:

PHP-Quellcode:
class User extends BaseTable
{

    public function getFields()
    {
        return array(
            "name" => new VarChar(255),
            "password" => new VarChar(32)
        );
    }

}
Das ist alles nur beispielsweise und auch nur ungefähr. Vieles davon kann man ändern. So ist der Weg, den ich kennen gelernt habe und zu schätzen weiß. Im Vergleich zu den vielen, recht simple gehaltenen Anwendungen, kann man das auch durchauss als "professionell" bezeichnen.

Fertige Implementationen von Ähnlichem (!) sind zum Beispiel Doctrine oder das Zend Framework. Ich persönliche bin total verliebt ( :love: ) in Django (Python) und leite von deren Strukturen auch vieles auf meine PHP-Apps ab.

Hoffe ich konnte dir damit helfen. PHP ist nicht so schlimm wie du immer denkst. Du machst es nur schlimm... PHP hat viele Nachteile, das kann man nicht abstreiten. Aber das sind nicht die, die du immer nennst. Schlechtes Design, inkonsequente APIs und unlogisches Verhalten definieren sich an ganz anderen Stellen in PHP. Aber auch damit lernt man umzugehen.

Liebe Grüße,
Valle :-)

alcaeus 9. Aug 2010 22:34

AW: PHP - sind hier "Sicherheitsexperten" an Board?
 
Zitat:

Zitat von himitsu (Beitrag 1040604)
PHP-Quellcode:
$Database->Select(Language, array('NameID' => $NameID));

Das? Dafuer brauchst du solches Konstantengedoens statt Klassennamen als String anzugeben? Wie vermutet liegt der Fehler oder das Problem nichtmal ansatzweise bei PHP sondern in der Architektur der Anwendung. Ohne den Code zu kennen: du uebergibst der Select-Funktion die Parameter fuer die Prepared Statements und den Namen der Klasse von dem die Objekte beim Zurueckgeben via FetchRow() sein sollen?
Erstens: wenn du deinem DB-Layer sagen musst, in welche Klasse er die Daten reinhydrieren soll dann hast du schon was falsch gemacht. Entweder das Ding weiss es von selbst oder du musst nochmal ans Zeichenbrett.
Zweitens: in dem Codebeispiel von vorhin ist es absolut sinnbefreit, eine Hydrierung in Objekte vorzunehmen (die kostet richtig viel Zeit) nur um danach ein Array zu befuellen. Da bist du von Anfang an mit Arrays besser bedient. Spaetestens wenn du mal ein paar Hundert Datensaetze ein paar Hunder mal auslesen musst, wirst du mir fuer den Tipp danken.
Drittens: hoer auf ein n-Eck zu entwickeln, es als Rad zu verkaufen und wenn man sagt "ne, das ist kein Rad" dann einfach ein n+1-Eck zu bauen und das Ganze von vorne losgehn zu lassen. Es mag jetzt boese klingen, aber es gibt zwei richtig gute Projekte (ok, ein richtig gutes und ein...naja, egal) die genau das Umsetzen was du da halbherzig mit ohne Features umgesetzt hast. Das Ganze nennt sich "Object-Relational Mapper" und kann das Hundertfache von dem was deine Library kann. Auch von mir kommt nochmal der bereits oft erwaehnte ernsthafte Rat, dir wenigstens Doctrine anzugucken. Wenn du selbstzerstoererisch veranlagt bist kannst du dir auch noch Propel angucken. Ich mag Doctrine lieber, aber ich erwaehn auch immer Propel.

Und jetzt eine ganz, ganz, ganz grosse Bitte: befasse dich bitte mit Software-Architektur. In Delphi wird einem viel vorgegeben, weshalb es schwer ist sich in den Fuss zu schiessen. Du hast ein winziges Projekt angefangen und hast dir mehr Fuesse weggeschossen als jemals Prothesen dafuer gebaut werden koennen. PHP ist eine Sprache die dich in kein Muster zwingt. Das ist auf der einen Seite sehr schoen, weil Quick'n'Dirty-Programming echt gut funktioniert. Wenn du aber Software entwickeln willst (im Unterschied zum ueblichen "Scripte basteln") dann befass dich bitte mit Patterns wie eben ORM, MVC, Factories, Singletons, Decorators. Zusaetzlich solltest du dir das Konzept der Dependency Injection angucken - all diese Dinge sind in der modernen SW-Entwicklung (und in meinen Augen v.a. in PHP) unerlaesslich.
Auch wenn du nur hobby-maessig PHP-Projekte entwickelst, als hauptberuflicher PHP-Entwickler tut es echt weh, diese Leier immer wieder erwaehnen zu muessen.

Greetz
alcaeus


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:24 Uhr.
Seite 8 von 8   « Erste     678   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz