ursus contionabundo: Zum Abschied: "Make it simple, stupid and also inexpensive!"

Beitrag lesen

Nachdem ich mich gestern an anderer Stelle aufgeregt habe, dass Dir keine einfache und wirklich passende Lösung angeboten wurde, hole ich das zum Abschied und zum Nachweis, dass ich kein Klug- und erst recht kein Dummschwätzer bin, nach:

Deine ursprüngliche Idee habe ich einfach mal herumgedreht. Die aufrufenden Skripte bleiben unverändert.

Schritt 1:

Dafür sorge tragen, dass der Webserver in das betreffende Verzeichnis mit den zu incudierenden lib-Dateien schreiben kann.

Schritt 2:

Diesen etwas langen "Einzeiler" in die "verdächtigen" libs setzen:

<?php
if ( is_file( __DIR__  . '/flag_log_opener_true' ) && ! is_file(__FILE__ . '_opener.txt' ) ) file_put_contents( __FILE__ . '_opener.txt' , realpath( $_SERVER['SCRIPT_NAME'] ) . PHP_EOL , FALSE );

(Ich denke, es ist selbsterklärend, was das macht. Wenn nicht: fragen, das sollten hier so zweidrei mehr beantworten können)

Schritt 3:

In der Shell mit touch flag_log_opener_true eine leere Datei im lib-Dir anlegen.

Schritt 4:

Warten oder wie unter c) beschrieben vorgehen.

Schritt 5:

Dateien mit der Endung "_opener.txt" bestaunen. Deren Existenz und Inhalt zeigt, dass die Datei, an deren Name "_opener.txt" angehangen wurde, mindestens einmal aufgerufen bzw. includiert wurde. ls reicht also um im von Dir bestimmten Umfang informiert zu sein.

Schritt 6:

mv flag_log_opener_true flag_log_opener_false; rm *_opener.txt

Diskussion:

a) Vorteile:

  1. Die Performancebremse "Datenbank" und vermeingefährliches Zeug wie eval() werden nicht genutzt.
  2. Bei meinem Test mit halbwegs leistungsfähiger Harware: 1 Mio Aufrufe der Zeile = 1.25 sek. - Ich denke aber, ein Einzelaufruf ist deutlich "teurer".
  3. Das Vorgehen ist vergleichsweise "simple, stupid and also inexpensive".
  4. Funktioniert auch bei dynamischer Einbindung.
  5. Stoppen einfach durch Löschen oder Umbenennen der Datei. 'flag_log_opener'. Und also leicht reaktivierbar.
  6. Keine "Überinformation" wie bei debug_backtrace().
  7. Keine Änderung Deiner Arbeitsweise nötig.

b) Nachteile:

  1. Setzt einen Abruf voraus, es gibt also keine Garantie, dass ein Aufruf registriert wird obwohl das Skript doch noch irgendwo eingebunden ist.
  2. Braucht die Schreibrechte am Verzeichnis.
  3. Du änderst Deine Arbeitsweise nicht. Eine IDE wäre tatsächlich hilfreicher. (Übrigens scheitern die auch bei vielen dynamischen Einbindungen)

c) Behebung der Nachteile und deren Folgen:

  • Der Abruf kann durch etwas wie wget --delete-after -mrk https://example.com/ erzwungen werden. Das füllt aber keine Formulare aus, ebenso wird Javascript nicht ausgeführt. Außerdem hält sich wget an die robots.txt (man wget zeigt wie man das ändert)
  • Anderes Verzeichnis benutzen.

Es gibt eine weitere Variante:

<?php
if ( is_file( __DIR__  . '/flag_log_opener_true' ) ) file_put_contents( __FILE__ . '_opener.txt' , realpath( $_SERVER['SCRIPT_NAME'] ) . PHP_EOL, FILE_APPEND );

Diese schreibt jeden Zugriff mit und macht also mehr als gefordert. Das kann aber ohne "teure" Gegenmaßnahmen zum Überlauf der Platte führen. Wenn Du nun

<?php
if ( is_file( __DIR__  . '/flag_log_opener_true' ) ) file_put_contents( __FILE__ . '_opener.txt' , date('Y-m-d H:i:s') . PHP_EOL . var_export( debug_backtrace(), TRUE ) . PHP_EOL . PHP_EOL, FILE_APPEND );

einträgst, dann bist Du praktisch bei einer Variante der Lösung von dedlfix. Dieses debug_backtrace() liefert halt mehr Informationen als Du wolltest. Kann aber sein, genau die interessieren jemand anderes.