oxo888oxo: Was macht diese Zeile PHP code genau?

0 56

Was macht diese Zeile PHP code genau?

oxo888oxo
  • php
  1. 1
    dedlfix
    1. 0
      Tabellenkalk
      1. 0
        oxo888oxo
      2. 0
        dedlfix
        1. 0

          Hier nun doch mal das ganze Script

          oxo888oxo
          1. 0
            dedlfix
            1. 0
              oxo888oxo
              1. 0
                Rolf B
                1. 0
                  oxo888oxo
          2. 0
            Rolf B
            1. 0
              oxo888oxo
              1. 0
                dedlfix
                1. 0
                  oxo888oxo
                  1. 0
                    dedlfix
                    1. 0
                      oxo888oxo
                  2. 0
                    Rolf B
                    1. 0
                      dedlfix
          3. 2
            Mitleser 2.0
            1. 0
              oxo888oxo
              1. 0
                Mitleser 2.0
                1. 0
                  oxo888oxo
                2. 0

                  PHP: error_log();

                  Raketenlogbuchschreiber
                  1. -1
                    Raketenlogbuchschreiber
                    1. 0

                      Verwendungsbeispiel

                      Raketenlogbuchschreiber
                  2. 0

                    PHP: error_log(); Logrotate

                    TS
                    • linux
                    • php
                    1. 0
                      Raketenlogbuchschreiber
            2. 1
              dedlfix
              1. 0
                TS
                • dateisystem
                • php
                • webserver
                1. 0
                  Mitleser 2.0
                  1. 0
                    Frank
                    1. 0
                      Raketenfleischwurst
                      1. 0

                        Zum Forum

                        Raketenfleischwurst
                        • zu diesem forum
                        1. 0
                          Der Martin
                          1. 0
                            Raketenfleischwurst
                            1. 0
                              Raketenwissenschaftler
                              1. 0
                                klawischnigg
                                1. 0
                                  Raketenwissenschaftler
                                  1. 0
                                    klawischnigg
                                    1. 0
                                      Raketenwissenschaftler
                                  2. 0
                                    Raketenfleischwurst
                              2. 0
                                Amateurpsychologe
                                1. 0
                                  Raketenennachrichtenempfangsbestätiger
                        2. 0
                          Rolf B
                          1. 0
                            Raketenwissenschaftler
                            1. 4
                              Tabellenkalk
                          2. 0
                            Der Martin
                            1. -2
                              Raketenwilli
                              1. 0
                                Martl
                                • menschelei
              2. 0
                Frank
              3. 0

                Mail? Wirklich?

                Raketeneinwandfinder
      3. 0
        TS
    2. 0
      TS
      • logik
      • php
      • programmiertechnik
  2. 0
    Rolf B
    1. 0
      Der Martin
      1. 0
        oxo888oxo

Hallo

Ich habe in PHP ja nur gaaanz einfache Kenntnisse. Nun habe ich hier ein bisschen PHP Code, bei dem ich noch nicht so richtig begreife, was der genau macht.

if (isset($_SERVER['HTTP_REFERER']) && ($_SERVER!= "")){ echo "Hallo"; }

Wir da jetzt geprüft, ob die Variable $_SERVER['HTTP_REFERER' leer ist? Und nur, wenn sie nicht leer ist, wird "Hallo" ausgegeben? Und wenn ja, was genau macht denn dieses && in dem Code?

Könnte Ihr mir da helfen, das korrekt zu verstehen?

Gruß Ingo

  1. Tach!

    if (isset($_SERVER['HTTP_REFERER']) && ($_SERVER!= "")){ echo "Hallo"; }

    Wir da jetzt geprüft, ob die Variable $_SERVER['HTTP_REFERER' leer ist?

    Was isset() macht, steht im Handbuch.

    Der Vergleich $_SERVER!= "" ist erstmal unsinnig, solange $_SERVER nicht per Hand geändert wurde. Ansonsten ist $_SERVER ein Array und ein Vergleich mit einem String ergibt erstmal keinen Sinn. Um ein Array mit einem String zu vergleichen, konvertiert PHP das Array in einem String. Dabei kommt aber der String "Array" raus, und der ist kein Leerstring. Der Vergleich ergibt im Falle eines Arrays also immer true. Wäre $_SERVER allerdings nicht vorhanden, würde ein Zugriff darauf einen Fehler vom Typ Notice erzeugen. PHP macht bei solchen Fehlern weiter und gibt NULL als Wert für $_SERVER zurück. Der Vergleich von Leerstring mit NULL ergibt true, im vorliegenden Fall negiert, also false. Nun ist $_SERVER aber im Normalfall immer vorhanden und ein Array, solange man es nicht händisch beeinflusst hat oder es per Konfiguration ausgeschaltet wurde. Beides macht man im Normalfall nicht.

    Und nur, wenn sie nicht leer ist, wird "Hallo" ausgegeben?

    So ist wohl der Plan.

    Und wenn ja, was genau macht denn dieses && in dem Code?

    Die Funktion des Operators steht auch im PHP-Handbuch.

    Im vorliegenden Fall ist der zweite Vergleich und damit die logische Und-Verknüpfung überflüssig. Wenn $_SERVER['HTTP_REFERER'] vorhanden ist, ist auch $_SERVER vorhanden und ein Array. Wenn es nicht vorhanden ist, ist der erste Teil false und weitere Vergleiche mit && verknüpft können das Ergbnis nicht mehr ändern. PHP wertet, wie viele andere Programmiersprachen, den Rest des Ausdruckes nicht mehr aus. Den Teil ab dem && kann man sich also in jedem Fall sparen.

    dedlfix.

    1. Hallo,

      So ist wohl der Plan.

      Der eigentliche Plan ist doch wohl, zu prüfen, ob der Referer vorhanden und nicht leer ist, oder?

      Gruß
      Kalk

      1. Hallo Kalk

        Der eigentliche Plan ist doch wohl, zu prüfen, ob der Referer vorhanden und nicht leer ist, oder?

        Ja genau, dass ist im Grunde der Plan. Im weiteren Verlauf des Scripts (welche ich hier nicht gezeigt habe), wird der Referer in eine Variable geschrieben und diese dann verwendet.

        Und wenn der Referer leer ist, gib es ja eine Fehlermeldung. Darum wollte ich das weitere Script mit der obigen if-Abfrage umschließen.

        Das funktioniert ja soweit auch. Ich habe mir das allerdings zusammen gegoogelt und wollte das doch gerne besser verstehen.

        Wie kann ich es denn machen, wenn ich jetzt nicht nur prüfen möchte, ob der Referer leer ist, sondern mit ODER auch noch, ob $_SERVER['HTTP_USER_AGENT'] leer ist?

        Wäre das wie folgt korrekt?

        if (isset($_SERVER['HTTP_REFERER']) && ($_SERVER!= "")) OR (isset($_SERVER['HTTP_USER_AGENT']) && ($_SERVER!= ""))
        

        Gruß Ingo

      2. Tach!

        So ist wohl der Plan.

        Der eigentliche Plan ist doch wohl, zu prüfen, ob der Referer vorhanden und nicht leer ist, oder?

        Kann gut sein. Dafür wäre der gezeigte Code aber nicht geeignet. Das könnte man auch einfacher mit !empty($_SERVER['HTTP_REFERER']) erreichen. Dazu muss dann gegebenenfalls auch noch eine Validitätsprüfung kommen, weil das Feld ja auch mit beliebigem Unrat gefüllt sein kann.

        dedlfix.

        1. Hallo

          Ich poste hier nun doch mal das ganze Script, damit es keine Missverständnisse gibt:

          <?php
          	/*Hier Einstellungen festlegen*/
          	$home="http://example.org";//Die Domain
          	$email="mail@example.org"; //Deine Email Adresse
           
          	/*Infos*/
          	$dateiname=$_SERVER['REQUEST_URI'];
          	$useragent=$_SERVER['HTTP_USER_AGENT'];
          
          	if (isset($_SERVER['HTTP_REFERER']) && ($_SERVER!= "")){
          		$refere=$_SERVER['HTTP_REFERER'];
          		/*Mail to Webmaster*/
          		$header  ="From:404 Bot - <$email>\n";
          		$text =
          "Seite: https://example.org$dateiname
          
          Quelle: $refere
          
          $useragent";
          		mail($email,"404 Bot",$text,$header);
            }
          ?>
          
          1. Tach!

            Ich poste hier nun doch mal das ganze Script, damit es keine Missverständnisse gibt:

            Erwartest du jetzt, dass ich dein Script so umschreibe, wie es eigentlich arbeiten soll? Ich habe bereits erklärt, warum dein gezeigter Code teilweise nicht sinnvoll ist. Dass du nicht nur den Code erklärt bekommen haben wolltest, sondern eigentlich was anderes haben möchtest, kam mit deiner Antwort auf Tabellenkalks Nachfrage raus. Wie man das richtigerweise abfragt, habe ich in meiner Antwort auf Tabellenkalk beschrieben. Der Rest liegt jetzt bei dir. Ich werden keinen fertigen Code für dich schreiben. Aber Fragen zum Verständnis kannst du gern stellen.

            dedlfix.

            1. Hallo

              Erwartest du jetzt, dass ich dein Script so umschreibe, wie es eigentlich arbeiten soll?

              Nein, natürlich nicht. das Script arbeitet ja so wie es soll.

              Ich wollte eben nur den Teil aus meinem Ursprungs-Posting richtig verstehen, damit ich evtl. ohne fremde Hilfe dort noch was ergänzen kann.

              Gruß Ingo

              1. Hallo oxo888oxo,

                das Script arbeitet ja so wie es soll.

                So, wie Du es geschrieben hast, ist das sicher nicht der Fall. Es geht mit leeren REFERER-Angaben falsch um.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. Hallo Rolf

                  So, wie Du es geschrieben hast, ist das sicher nicht der Fall. Es geht mit leeren REFERER-Angaben falsch um.

                  Ah OK. Ist denn die folgende Variante korrekt?

                  <?php
                  	/*Hier Einstellungen festlegen*/
                  	$home="http://example.org";//Die Domain
                  	$email="mail@example.org"; //Deine Email Adresse
                   
                  	/*Infos*/
                  	$dateiname=$_SERVER['REQUEST_URI'];
                  	$useragent=$_SERVER['HTTP_USER_AGENT'];
                  
                  	if !empty($_SERVER['HTTP_REFERER']){
                  		$refere=$_SERVER['HTTP_REFERER'];
                  		/*Mail to Webmaster*/
                  		$header  ="From:404 Bot - <$email>\n";
                  		$text =
                  "Seite: https://example.org$dateiname
                  
                  Quelle: $refere
                  
                  $useragent";
                  		mail($email,"404 Bot",$text,$header);
                    }
                  ?>
                  
          2. Hallo oxo888oxo,

            ihr schreibt alle zu schnell 😂

            Also - wenn überhaupt, müsstest Du nicht $_SERVER auf ungleich "" testen, sondern $_SERVER['HTTP_REFERER']. Da ist Dir beim Kopieren was verloren gegangen.

            Und wie Dedlfix schrieb: dafür gibt's was fertiges: !empty(...).

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Rolf

              Also - wenn überhaupt, müsstest Du nicht $_SERVER auf ungleich "" testen, sondern $_SERVER['HTTP_REFERER']. Da ist Dir beim Kopieren was verloren gegangen.

              Und wie Dedlfix schrieb: dafür gibt's was fertiges: !empty(...).

              Wäre das dann so korrekt?

              <?php
              	/*Hier Einstellungen festlegen*/
              	$home="http://example.org";//Die Domain
              	$email="mail@example.org"; //Deine Email Adresse
               
              	/*Infos*/
              	$dateiname=$_SERVER['REQUEST_URI'];
              	$useragent=$_SERVER['HTTP_USER_AGENT'];
              
              	if !empty($_SERVER['HTTP_REFERER']){
              		$refere=$_SERVER['HTTP_REFERER'];
              		/*Mail to Webmaster*/
              		$header  ="From:404 Bot - <$email>\n";
              		$text =
              "Seite: https://example.org$dateiname
              
              Quelle: $refere
              
              $useragent";
              		mail($email,"404 Bot",$text,$header);
                }
              ?>
              
              1. Tach!

                Wäre das dann so korrekt?

                Ein Klammernpaar fehlt noch beim if. Damit wäre der Code syntaktisch korrekt und auch in Bezug auf die Leer-Prüfung. Ich bezweifle aber, dass du nur dann eine Mail bekommen möchtest, wenn der Referrer vorhanden ist. Vermutlich möchtest du den Mail-Text in Abhängigkeit vom Vorhandensein des Referrers mal mit und mal ohne ihn schreiben. Da es sich hier wohl nur eine Mail zu Administrationszwecken handelt, muss man es nicht komplizierter als nötig machen. Ich würde gar nicht prüfen, ob der Referrer vorhanden ist, sondern einfach den Wert in den Mailtext schreiben. Also genau so, wie du mit dem UserAgent umgehst. Ist er da, steht er drin, ist er es nicht, kommt NULL raus und das wird zu einem Leerstring konvertiert, wenn es in den String vom Mailtext eingefügt wird.

                dedlfix.

                1. Tach!

                  Wäre das dann so korrekt?

                  Ein Klammernpaar fehlt noch beim if.

                  Ah ja stimmt. Danke. So dann, richtig?

                  if (!empty($_SERVER['HTTP_REFERER'])){

                  Ich bezweifle aber, dass du nur dann eine Mail bekommen möchtest, wenn der Referrer vorhanden ist.

                  Doch. Ich möchte keine Mail versenden, wenn der Referer leer ist.

                  Ich würde gar nicht prüfen, ob der Referrer vorhanden ist, sondern einfach den Wert in den Mailtext schreiben. Also genau so, wie du mit dem UserAgent umgehst. Ist er da, steht er drin, ist er es nicht, kommt NULL raus und das wird zu einem Leerstring konvertiert, wenn es in den String vom Mailtext eingefügt wird.

                  Ja das hatte ich zuerst auch so. Die Mails werden dann auch versendet, aber PHP gibt eine Fehlermeldung.

                  1. Tach!

                    Ja das hatte ich zuerst auch so. Die Mails werden dann auch versendet, aber PHP gibt eine Fehlermeldung.

                    Die Fehlermeldung bekommt man auch anders gelöst. Zum einen sollte im Produktivbetrieb sowieso die Anzeige der Fehlermeldungen ausgeschaltet sein (display_errors). Der Text ist für Anwender mindestens uninteressant. Damit aber auch nicht das Logfile vollgemüllt wird, kann man die Anweisung, in der auf eventuell nicht vorhandene Werte zugegriffen wird, mit einem @ davor versehen werden.

                    Das @ ist aber kein Allheilmittel zum Beseitigen von Fehlern. Der Einsatz sollte bedacht erfolgen, und nicht überall, wo Meldungen auftreten können.

                    dedlfix.

                    1. Moin

                      Zum einen sollte im Produktivbetrieb sowieso die Anzeige der Fehlermeldungen ausgeschaltet sein (display_errors).

                      Ja das habe ich bei mir natürlich auch so.

                      Damit aber auch nicht das Logfile vollgemüllt wird

                      Genau darum geht es mir. Ich stehe drauf, wenn sich dort keine Fehler offenbaren. Also ich meine natürlich, wenn meine Scripte eben gar keine Fehler verursachen.

                      kann man die Anweisung, in der auf eventuell nicht vorhandene Werte zugegriffen wird, mit einem @ davor versehen werden.

                      OK das gucke ich mir mal genauer an.

                  2. Hallo oxo888oxo,

                    Die Mails werden dann auch versendet, aber PHP gibt eine Fehlermeldung.

                    Dann hast Du was anderes falsch gemacht.

                    Du kannst Dir Arbeit sparen, wenn Du die filter_input Funktion verwendest.

                    $referer = filter_input(INPUT_SERVER, "HTTP_REFERER");
                    
                    $text =
                    "Seite: https://example.org$dateiname
                    
                    Quelle: $referer
                    
                    $useragent";
                    

                    Aber gut ist das auch nicht. Für mehrzeilige Strings nimmt man eigentlich heredoc-Strings:

                    $text = <<<EOS
                    Seite: https://example.org$dateiname
                    
                    Quelle: $referer
                    
                    $useragent
                    EOS;
                    

                    Wobei das auch noch nicht das Beste ist. Ich würde das mit dem Ausgabepuffer lösen. PHP ist eine Sprache für Templates, nicht für Stringverkettung:

                    ob_start();
                    ?>
                    Seite: https://example.org<?= filter_input(INPUT_SERVER, "REQUEST_URI") ?>
                    
                    Quelle: <?= filter_input(INPUT_SERVER, "HTTP_REFERER") ?>
                    
                    <?= filter_input(INPUT_SERVER, "HTTP_USER_AGENT") ?>
                    <?php
                    $text = ob_get_clean();
                    

                    Dieses Script schaltet die Ausgabepufferung ein, d.h. alles, was das Script jetzt ausgibt, wird zwischengespeichert. Dann wird der PHP Modus beendet und der Mail-Body "ausgegeben". Der geht in den Puffer. Die variablen Werte werden mit <?= ... ?> in den Text eingebaut. filter_input kümmert sich darum, dass fehlende $_SERVER-Einträge zum Leerstring werden.

                    Danach geht's zurück nach PHP und der Buffer wird mit ob_get_clean ausgelesen und geleert.

                    Was mir derzeit nicht klar ist, ist die Frage, ob man für einen Mail-Body Zeichen maskieren muss oder ob man blindlings den Inhalt der $_SERVER-Werte hinausrotzen kann. Du erzeugst dem Anschein nach keine HTML Mail, deshalb braucht es keine HTML Maskierung. Aber vielleicht eine andere. Dedlfix? Weißt Du das?

                    Rolf

                    --
                    sumpsi - posui - obstruxi
                    1. Tach!

                      Was mir derzeit nicht klar ist, ist die Frage, ob man für einen Mail-Body Zeichen maskieren muss oder ob man blindlings den Inhalt der $_SERVER-Werte hinausrotzen kann.

                      Kann man.

                      Du erzeugst dem Anschein nach keine HTML Mail, deshalb braucht es keine HTML Maskierung.

                      Stimmt auch. Default-Content-Type ist text/plain.

                      Aber vielleicht eine andere. Dedlfix? Weißt Du das?

                      Es gibt ein paar Regeln für die Formatierung beim Versand, zum Beispiel wenn einzelne Punkte in einer Zeile vorkommen, aber darum kümmert sich PHP oder darunter liegende Schichten.

                      Für Headerzeilen siehe aber Kontextwechsel erkennen und behandeln → E-Mail.

                      dedlfix.

          3. Abseits Deiner konkreten Fragen: verstehe ich das richtig, Du willst Dir bei jedem 404er mit verfügbarem Referrer ne Mail zur Prüfung schicken lassen?

            Lass das lieber bleiben. Wenn ein böser Bot über Deine Seite rauscht und z.B. 1000 404er mit irgendwelchen Referrern produziert, dann haust Du auf einmal 1000 Mails raus. Dann dreht Dir Dein Provider den Hahn ab, bzw. der Server landet dann schnell auf Blacklists.

            Die Logfiles des Webservers sollten die nötigen Information schon beinhalten, Du musst die nur sichten / filtern.

            Wenn es denn wirklich was Eigenes sein soll, dann schreib Dir die Daten in ein Textfile weg. Wenn des denn wirklich eine Mail sein soll, dann richte Dir einen Cronjob ein, der das Textfile z.B. alle 30 Minuten auf Veränderung prüft und Dir per Mail ne Info über den Status gibt. Aber für jeden 404er ne Mail rausjagen ist keine gute Idee.

            1. Hallo Mitleser

              Wenn es denn wirklich was Eigenes sein soll, dann schreib Dir die Daten in ein Textfile weg.

              Ah ja, ich danke Dir sehr für Deinen Einwand bezüglich E-Mail. Das mit der Text-Datei ist eine gute Idee. Nur weis ich leider nicht, wie ich das machen kann. Dafür kann ich leider PHP nicht gut genug.

              Gruß Ingo

              1. Ah ja, ich danke Dir sehr für Deinen Einwand bezüglich E-Mail. Das mit der Text-Datei ist eine gute Idee. Nur weis ich leider nicht, wie ich das machen kann. Dafür kann ich leider PHP nicht gut genug.

                Let Me Google That For You

                1. Hallo

                  Let Me Google That For You

                  Wink verstanden :-) Ich werde mich da mal einlesen.

                2. Der Hinweis auf Google ist ja nicht falsch.

                  Zielführender wäre aber ein Begriff wie "log" gewesen:

                  <?php
                  
                  error_log(
                      'Hallo Welt' . PHP_EOL,
                      3,
                      "/tmp/hallo.txt"
                  );
                  
                  echo "Getan." . PHP_EOL;
                  

                  Fehlt noch der Hinweis darauf, dass die Datei regelmäßig (oder bei Bedarf) gelöscht, geleert oder gekürzt werden sollte. Freilich kann man auch die Funktionen von logrotate nachbauen.

                  1. Bevor gemeckert wird:

                    ini_set( 'error_log', '/tmp/php-error.log' );
                    user_error( 'Huch! Was passiert', E_USER_Notice );
                    

                    kenne ich natürlich. Einen Ersatz für Logrotate braucht es natürlich trotzdem.

                    Hier ein unvollständiger Ansatz zum Testen:

                    <?php
                    
                    class phpLogger {
                    	var $logDir = '/tmp';
                    	var $logName = '404.log';
                    	
                    	var $maxFileSize = 60; #zum Testen
                    	#var $maxFileSize = 10485760; #10MB
                    
                    	var $maxOldLogs  = 3;
                    	var $logStyle    = false; # false: error_log(text) / E_USER_NOTICE ... E_USER_ERROR
                    	var $logFile = false;
                    
                    	function __construct() {
                    		
                    		if ( ! is_writable( $this -> logDir ) ) {
                    			trigger_error( 'Das Verzeichnis "' . $this -> logDir . '" existiert nicht.', E_USER_WARNING );
                    			$this -> enabled = false;
                    			return false;
                    		}
                    		if ( ! is_writable( $this -> logDir ) ) {
                    			trigger_error( 'Das Verzeichnis "' . $this -> logDir . '"ist nicht beschreibbar.', E_USER_WARNING );
                    			$this -> enabled = false;
                    			return false;
                    		}
                    		
                    		$this -> logFile = $this -> logDir . '/' . $this -> logName;
                    		if ( 
                    			     is_file ( $this -> logFile )
                    			and filesize ( $this -> logFile ) >= $this -> maxFileSize
                    		) {
                    				if ( 0 == $this -> maxOldLogs ) {
                    						file_put_contents( $this -> logFile, '' );
                    						return true;
                    				} else {
                    					$f = $this -> logFile . '.' . ( $this -> maxOldLogs ) . 'gz';
                    					if ( is_file ( $f ) ) { unlink( $f ); }
                    				}
                    				if ( 0 < $this -> maxOldLogs ) {
                    					for ( $i = $this -> maxOldLogs -1 ; $i > 0; $i-- ) {
                    						if ( $i > 1 ) {
                    							$o = $this -> logFile . '.' . strval( $i - 1 ) . '.gz';
                    						} else {
                    							$o = $this -> logFile . '.gz';
                    						}
                    						$n = $f = $this -> logFile . '.' . strval( $i ) . '.gz';
                    						if (is_file ( $o ) ) { 
                    							rename ( $o, $n );
                    						}
                    					}
                    				}
                    				$sys = 'gzip ' . escapeshellarg( $this -> logFile );
                    				exec( $sys );
                    				file_put_contents(  $this -> logFile, '' );
                    		}	
                    	} 
                    
                    	function log( $s ) {
                    		
                    		if ( $this -> logFile ) {
                    			if ( NULL == $this -> logStyle ) {
                    				error_log (
                    					trim( $s ) . PHP_EOL,
                    					3,
                    					$this -> logFile
                    				);
                    			} else {
                    				ini_set( 'error_log', $this -> logFile );
                    				user_error( trim( $s ), E_USER_NOTICE );
                    			}
                    		}
                    	}
                    }
                    
                    $logger = new phpLogger();
                    $logger -> log( 'Hallo Welt' );
                    
                    1. include $conf['libDir'] . 'phpLogger.php';
                      $logger = new phpLogger();
                      $logger -> log( 'Sicherlich will da noch jemand anders etwas Konstruktives beitragen.' );
                      
                  2. Hello,

                    Der Hinweis auf Google ist ja nicht falsch.

                    Zielführender wäre aber ein Begriff wie "log" gewesen:

                    <?php
                    
                    error_log(
                        'Hallo Welt' . PHP_EOL,
                        3,
                        "/tmp/hallo.txt"
                    );
                    
                    echo "Getan." . PHP_EOL;
                    

                    Fehlt noch der Hinweis darauf, dass die Datei regelmäßig (oder bei Bedarf) gelöscht, geleert oder gekürzt werden sollte. Freilich kann man auch die Funktionen von logrotate nachbauen.

                    Logrotate muss man nur konfigurieren, dass es die Datei im /tmp/-Verzeichnis ebenfalls beaufsichtigen soll.

                    Alternativ legt man die Datei besser ins /var/log/-Verzeichnis. Dann muss man höchstwahrscheinlich gar nichts nachbessern.

                    Glück Auf
                    Tom vom Berg

                    --
                    Es gibt nichts Gutes, außer man tut es!
                    Das Leben selbst ist der Sinn.
                    1. Fehlt noch der Hinweis darauf, dass die Datei regelmäßig (oder bei Bedarf) gelöscht, geleert oder gekürzt werden sollte. Freilich kann man auch die Funktionen von logrotate nachbauen.

                      Logrotate muss man nur konfigurieren, dass es die Datei im /tmp/-Verzeichnis ebenfalls beaufsichtigen soll.

                      Alternativ legt man die Datei besser ins /var/log/-Verzeichnis. Dann muss man höchstwahrscheinlich gar nichts nachbessern.

                      Es braucht für beides Root-Rechte, also einen eigenen (virtuellen) Server. Sowas hat längst nicht jeder und die mit den erforderlichen Rechten sollten eigentlich wissen, dass die mein Skript nicht brauchen. (Den Gegenbeweis hat „Anon mit der Maus“ geliefert.

            2. Tach!

              Lass das lieber bleiben. Wenn ein böser Bot über Deine Seite rauscht und z.B. 1000 404er mit irgendwelchen Referrern produziert, dann haust Du auf einmal 1000 Mails raus. Dann dreht Dir Dein Provider den Hahn ab, bzw. der Server landet dann schnell auf Blacklists.

              Der Einwand ist berechtigt. Zumindest, wenn man die Mails über fremde Infrastruktur versendet. Wenn man Herr über das eigene System ist, und die Mail nur intern in Postfächer kopiert wird, ist das nicht so tragisch. Allerdings will man auch da keine Unmenge an Mails sichten und löschen. Jede Mail ist Handarbeit. Und wenn mehrere Mails wegen derselben Ursache eintrudeln, wird es irgendwann langweilig.

              Statt Mails zu senden eine Textdatei zu erweitern, scheint da die bessere Idee zu sein. Wenn das Format eines ist, dass man zum Beispiel in Excel einlesen kann, kann man nach Quelle sortieren und die gleichartigen Zeilen recht einfach löschen.

              Bei Textdateien im Multiuser-Betrieb muss man aber konkurrierende Zugriffe beachten. Wenn zwei Vorgänge die Datei zur selben Zeit lesen, haben beide denselben Text im Puffer. Jeder hängt aber eigene Informationen an, und wer zuletzt schreibt, überschreibt die Änderungen des anderen.

              file_put_contents() mit dem Flag FILE_APPEND sollte die Angelegenheit regeln. Man übergibt PHP nur den anzuhängenden Teil, und muss nicht ein Einzelschritten öffnen, lesen, anhängen und zurückschreiben.

              Eine Datenbank zu verwenden und neue Einträge nur zu schreiben, wenn die Quelle noch nicht vorhanden ist (Unique Key auf die Quelle legen, einfach Insert, und Fehler wegen Unique Key Contraints ignorieren), wäre auch eine Alternative.

              dedlfix.

              1. Hello,

                Statt Mails zu senden eine Textdatei zu erweitern, scheint da die bessere Idee zu sein. Wenn das Format eines ist, dass man zum Beispiel in Excel einlesen kann, kann man nach Quelle sortieren und die gleichartigen Zeilen recht einfach löschen.

                Bei Textdateien im Multiuser-Betrieb muss man aber konkurrierende Zugriffe beachten. Wenn zwei Vorgänge die Datei zur selben Zeit lesen, haben beide denselben Text im Puffer. Jeder hängt aber eigene Informationen an, und wer zuletzt schreibt, überschreibt die Änderungen des anderen.

                Ein APPEND als Öffnungsmodus sollte es regeln :-)

                Viel spannender ist dann mMn, wo man die Datei speichert, bzw. wie man ihre Größe im Zaum hält. Sinnvoll wäre es z. B., sie im zugewiesenen LOG-Verzeichnis anzulegen, das dann hoffentlich von logrorate beaufsichtigt wird.

                Glück Auf
                Tom vom Berg

                --
                Es gibt nichts Gutes, außer man tut es!
                Das Leben selbst ist der Sinn.
                1. Ein APPEND als Öffnungsmodus sollte es regeln :-)

                  Schrieb dedlfix das nicht bereits?

                  Viel spannender ist dann mMn, wo man die Datei speichert, bzw. wie man ihre Größe im Zaum hält. Sinnvoll wäre es z. B., sie im zugewiesenen LOG-Verzeichnis anzulegen, das dann hoffentlich von logrorate beaufsichtigt wird.

                  Viel spannender ist dann mMn, warum man überhaupt was Eigenes bauen muss, wenn dass access.log doch bereits alle Informationen enthält.

                  Ne selbstgebaute Lösung in das Lograte des OS zu bekommen, scheint mir unwahrscheinlich. oxo888oxo's Fragen lassen nicht darauf schließen, dass er Admin auf dem System ist.

                  1. Hi Laberkopp,

                    Ein APPEND als Öffnungsmodus sollte es regeln :-)

                    Schrieb dedlfix das nicht bereits?

                    Viel spannender ist dann mMn, wo man die Datei speichert, bzw. wie man ihre Größe im Zaum hält. Sinnvoll wäre es z. B., sie im zugewiesenen LOG-Verzeichnis anzulegen, das dann hoffentlich von logrorate beaufsichtigt wird.

                    Viel spannender ist dann mMn, warum man überhaupt was Eigenes bauen muss, wenn dass access.log doch bereits alle Informationen enthält.

                    Ob alle im Einzelfall zu loggenden Informationen im Standard-Access-Log oder im Standard-Error-Log vorhanden sind, müsste der OP erst prüfen.

                    Ne selbstgebaute Lösung in das Lograte des OS zu bekommen, scheint mir unwahrscheinlich. oxo888oxo's Fragen lassen nicht darauf schließen, dass er Admin auf dem System ist.

                    Was könnte da denn Schwierigkeiten bereiten? Erzähl doch mal!

                    Wenn er mit PHP gar nicht aufs Logfile zugreifen darf, müsste wohl eine eigene Lösung her für die gewünschte automatische Auswertung.

                    Greets
                    Frank

                    1. Hi Laberkopp,

                      Hallo Wurst!

                      Ob alle im Einzelfall zu loggenden Informationen im Standard-Access-Log oder im Standard-Error-Log vorhanden sind, müsste der OP erst prüfen.

                      Für eine Standardkonfiguration Apache? In Bezug auf OPs eigentliches Ziel? Ja.

                      Was könnte da denn Schwierigkeiten bereiten? Erzähl doch mal!

                      Wie SCHREIBST Du denn in ein in der Standardkonfiguration von Vhost X unter „Linux der Wahl“ in ein von logrotate überwaches Verzeichnis? Erzähl doch mal!

                      Wenn er mit PHP gar nicht aufs Logfile zugreifen darf, müsste wohl eine eigene Lösung her für die gewünschte automatische Auswertung.

                      Ach was!

                      1. Die schon seit längerem fehlende Möglichkeit der nachträglichen Editierung eines Beitrags für nicht registrierte User ist sehr, sehr ärgerlich :-( Hat das DSGVO-Gründe? Bis vor einigen Monaten ging das ja noch.

                        1. Hallo,

                          Die schon seit längerem fehlende Möglichkeit der nachträglichen Editierung eines Beitrags für nicht registrierte User ist sehr, sehr ärgerlich :-( Hat das DSGVO-Gründe? Bis vor einigen Monaten ging das ja noch.

                          meines Wissens geht das immer noch, dafür müssen aber drei Voraussetzungen erfüllt sein:

                          1. Das Posting darf noch nicht zu alt sein (IIRC 10min)
                          2. Es darf noch kein Folgeposting haben
                          3. Der Schreiber muss Cookies von selfhtml.org zulassen

                          Sollte das falsch sein, dann ist die Änderung auch an mir vorbeigegangen. Mit der DSGVO sehe ich jedenfalls keinen Zusammenhang - wenn das der Grund wäre, hätte das Feature ja schon vor gut drei Jahren wegfallen müssen (die DSGVO ist seit Ende Mai 2018 verbindlich).

                          Live long and pros healthy,
                           Martin

                          --
                          Klein φ macht auch Mist.
                          1. meines Wissens geht das immer noch, dafür müssen aber drei Voraussetzungen erfüllt sein:

                            1. Das Posting darf noch nicht zu alt sein (IIRC 10min)
                            2. Es darf noch kein Folgeposting haben
                            3. Der Schreiber muss Cookies von selfhtml.org zulassen

                            Bei mir alle drei Vorgaben eben erfüllt. Dennoch wurde mir kein Button „Bearbeiten“ angeboten. Wie gesagt, seit einigen Monaten ist das so...

                            1. Oh! Ich habe also tatsächlich einen Fanclub.

                              1. Oh! Ich habe also tatsächlich einen Fanclub.

                                Ja, wahrscheinlich der Wernher von Braun-Revival-Club in Castrop Rauxel...

                                1. Ja, wahrscheinlich der Wernher von Braun-Revival-Club in Castrop Rauxel...

                                  Ah(¹)! Hier mal ein Hinsehtipp.

                                  ¹) Auch wenn ich mit dem Name nichts anfangen kann.

                                  1. Ja, wahrscheinlich der Wernher von Braun-Revival-Club in Castrop Rauxel...

                                    Ah(¹)! Hier mal ein Hinsehtipp.

                                    ¹) Auch wenn ich mit dem Name nichts anfangen kann.

                                    Willst Du mir helfen meine Beiträge zu formatieren oder wie soll ich Deine Replik verstehen...?

                                    1. Willst Du mir helfen meine Beiträge

                                      Dir nicht nicht. Aber dem „Wernher von Braun-Revival-Club“ in Castrop Rauxel.

                                  2. Ah(¹)! Hier mal ein Hinsehtipp.

                                    Die Checkbox habe ich erfolgreich übersehen. Merci!

                              2. Der Nächste bitte!

                                Oh! Ich habe also tatsächlich einen Fanclub.

                                Äh, weiß dein Therapeut von diesen Wahnvorstellungen?

                                Gute Besserung!

                                1. Äh, weiß dein Therapeut von diesen Wahnvorstellungen?

                                  Aha.

                        2. Hallo Raketenfleischwurst,

                          dann registrier Dich doch einfach wieder. Musst Dich ja nicht als ****x oder ***g ***z registrieren - aber wenn die Rakete schreibt, weiß eh jeder wer das ist. Und schon ist alles viel einfacher. Es sei denn, du hast Angst, dass sich negative Bewertungen kumulieren. Aber es gibt ja ggf. auch mal positive 😉

                          Rolf

                          --
                          sumpsi - posui - obstruxi
                          1. Hallo Raketenfleischwurst,

                            dann registrier Dich doch einfach wieder. Musst Dich ja nicht als ****x oder ***g ***z registrieren

                            Das möchte ich mir doch seitens derjenigen Person, welche sich in provokativer Absicht „Raketenfleischwurst“ nennt, so höflich wie bestimmt verbitten.

                            1. Hallo,

                              Das möchte ich mir doch seitens derjenigen Person, welche sich in provokativer Absicht „Raketenfleischwurst“ nennt, so höflich wie bestimmt verbitten.

                              Du meinst, da hat jemand dein Schema F, mit dem du dir regelmäßig neue Namen gibst, das aber so gestaltet ist, dass man dich trotzdem erkennt, gehackt? Ach wenn es doch bloß eine Möglichkeit gäbe, einen Teilnehmer an einer eindeutigen Id oder Bezeichnung oder sowas zu erkennen...

                              Gruß
                              Kalk

                          2. Hallo Rolf,

                            Hallo Raketenfleischwurst,

                            dann registrier Dich doch einfach wieder. Musst Dich ja nicht als ****x oder ***g ***z registrieren - aber wenn die Rakete schreibt, weiß eh jeder wer das ist.

                            das stimmt wohl, aber dann könnte er nicht mehr so hopplahopp von einem Beitrag zum anderen den Namen wechseln wie andere ihre Socken (wobei ich das sogar begrüßen würde).

                            Es sei denn, du hast Angst, dass sich negative Bewertungen kumulieren. Aber es gibt ja ggf. auch mal positive 😉

                            Eben, und eine positive gleicht zehn negative aus.

                            Live long and pros healthy,
                             Martin

                            --
                            Klein φ macht auch Mist.
                            1. dann könnte er nicht mehr so hopplahopp von einem Beitrag zum anderen den Namen wechseln

                              Hehe. Es macht aber Spaß, sich Wortungetüme auszudenken, die mit „Raketen“ beginnen und dann mit maximal weiteren 43 Zeichen einen Hinweis geben, was in der Nachricht steht (oder eine eigene Nachricht sind.)

                              Eben, und eine positive gleicht zehn negative aus.

                              So lange ich erleben muss, dass meine Beiträge so wortlos, grund- und wahlfrei negativ bewertet werden, während eindeutig in Beleidigungsabsicht geschriebenes Zeug anderer unbeanstandet stehen bleibt, sehe ich wenig Antrieb, mich anzumelden.

                              1. Dieser Beitrag wurde gesperrt: Der Beitrag ist unkonstruktiv oder provokativ und trägt zu einer Verschlechterung der Stimmung bei.

                                Hallo Rocketman,

                                dann meinet D. Trump also Dich und nicht Kim Jong-Un?

                                Grüße, Martl

              2. Hi Ox, hi dedlfix,

                Bei Textdateien im Multiuser-Betrieb muss man aber konkurrierende Zugriffe beachten. Wenn zwei Vorgänge die Datei zur selben Zeit lesen, haben beide denselben Text im Puffer. Jeder hängt aber eigene Informationen an, und wer zuletzt schreibt, überschreibt die Änderungen des anderen.

                file_put_contents() mit dem Flag FILE_APPEND sollte die Angelegenheit regeln. Man übergibt PHP nur den anzuhängenden Teil, und muss nicht ein Einzelschritten öffnen, lesen, anhängen und zurückschreiben.

                Ein $ft = fopen($filename, 'a') mit fwrite()sollte das auch schaffen.

                So hätte man zumindest noch die Möglichkeit, eventuelle Fehler beim Öffnen und Schreiben des Logs genauer zu bestimmen.

                Es gibt aber auch eine spezielle Logfunktion, die dann den offiziell eingerichteten Logkanal nutzen kann/sollte.

                Greets Frank

              3. Zumindest, wenn man die Mails über fremde Infrastruktur versendet. Wenn man Herr über das eigene System ist, und die Mail nur intern in Postfächer kopiert wird, ist das nicht so tragisch.

                Mit Mail-Headern und den Logs des oder der Mailserver erzeugt man so aber unter Umständen ganz schön viel Text…

                Sich mit SSH und tail zu befassen ist da deutlich billiger...

      3. Hello,

        So ist wohl der Plan.

        Der eigentliche Plan ist doch wohl, zu prüfen, ob der Referer vorhanden und nicht leer ist, oder?

        Kann man es wissen? Die enthaltenen Kommentare im Code sind mangels Vorahndensein jedenfalls nicht hilfreich ;-P

        Und wenn $_SERVER['HTTP_REFERER'] vorhanden ist, sollte es auch nicht leer sein können, da es dann von der PHP-Environment-Verarbeitung gar nicht erst angelegt werden würde.

        Glück Auf
        Tom vom Berg

        --
        Es gibt nichts Gutes, außer man tut es!
        Das Leben selbst ist der Sinn.
    2. Hello,

      [...]

      Im vorliegenden Fall ist der zweite Vergleich und damit die logische Und-Verknüpfung überflüssig. Wenn $_SERVER['HTTP_REFERER'] vorhanden ist, ist auch $_SERVER vorhanden und ein Array. Wenn es nicht vorhanden ist, ist der erste Teil false und weitere Vergleiche mit && verknüpft können das Ergbnis nicht mehr ändern. PHP wertet, wie viele andere Programmiersprachen, den Rest des Ausdruckes nicht mehr aus. Den Teil ab dem && kann man sich also in jedem Fall sparen.

      Oder man überlegt nochmal, was der Ur-Autor eigentlich bezwecken wollte und was er vielleicht vergessen hat.

      Vielleicht wollte er ja abfragen, ob $_SERVER['HTTP_REFERER'] einen sinnvollen Wert enhält, ob also eine gültige URL darin steckt?

      Dann müsste man aber noch weiter ins Detail gehen und einen Testaufruf auf die formal gültig erscheinende URL durchführen und schauen, ob der Response-Status einen angenehmen Wert (200) enthält. Sollte er einen 3xx-er enthalten, müsste man weiter entscheiden, usw.

      Glück Auf
      Tom vom Berg

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.
  2. Hallo Ingo,

    ich hätte zwei Hypothesen zur Erklärung dieser Abfrage:

    (1) Meine Historiker-Kenntnisse zu PHP sind nicht so ganz ausgeprägt, aber eins weiß ich: Im PHP 4 Handbuch steht neben $_SERVER noch $HTTP_SERVER_VARS als deprecated, und die Warnung, dass die beiden Variablen zwar zu Beginn das Gleiche enthalten würden, aber nicht gleich seien.

    Meine Mutmaßung - für die ich keine Dokumente finde - ist nun, dass es $_SERVER vor PHP 4 noch nicht gab. Wenn man also Code schrieb, der unter PHP 3 und 4 laufen sollte, musste man abfragen, ob $_SERVER vorhanden ist. Und eigentlich noch einen Fallback auf $HTTP_SERVER_VARS vorsehen.

    Diese Abfrage hat sich in irgendwelchen Samples erhalten und geistert nun durch die Welt, ohne dass man noch wüsste, was sie soll.

    Und jetzt sind wir 20 Jahre später. Von $HTTP_SERVER_VARS weiß niemand mehr etwas, und alle PHP Versionen der letzten 20 Jahre enthalten $_SERVER als Superglobal. Auf PHP 3 würden deine Scripte vermutlich nicht einmal laden, geschweige denn starten. Wenn Du denn überhaupt noch einen Server findest, auf dem PHP 3 überhaupt ladbar wäre.

    (2) Der Code, den Du da vorzeigst, stammt von jemandem, der ein unsolides Halbwissen über PHP hat und deshalb "zur Sicherheit" prüft, ob $_SERVER vorhanden ist. Solche Leute initialisieren eine Variable auch erstmal auf 0, bevor sie einen anderen Wert zuweisen.

    $_SERVER ist da. PHP stellt es Dir bereit. Du musst es nicht auf Existenz prüfen. Und schon gar nicht in dieser Reihenfolge; es ist nun reichlich Quatsch, ins "HTTP_REFERER" Fach vom Schrank zu greifen und erst danach zu schauen, ob da überhaupt ein Schrank steht.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo,

      $_SERVER ist da. PHP stellt es Dir bereit. Du musst es nicht auf Existenz prüfen.

      und dann auch nicht, indem man $_SERVER (ein Array!) mit einem Leerstring vergleicht.

      Und schon gar nicht in dieser Reihenfolge; es ist nun reichlich Quatsch, ins "HTTP_REFERER" Fach vom Schrank zu greifen und erst danach zu schauen, ob da überhaupt ein Schrank steht.

      😉

      Live long and pros healthy,
       Martin

      --
      Klein φ macht auch Mist.
      1. Hallo Martin

        Ich habe das Script jetzt wie folgt geändert:

        <?php
        	/*Hier Einstellungen festlegen*/
        	$home="http://example.org";//Die Domain
        	$email="mail@example.org"; //Deine Email Adresse
         
        	/*Infos*/
        	$dateiname=$_SERVER['REQUEST_URI'];
        	$useragent=$_SERVER['HTTP_USER_AGENT'];
        
        	if (!empty($_SERVER['HTTP_REFERER'])){
        		$refere=$_SERVER['HTTP_REFERER'];
        		/*Mail to Webmaster*/
        		$header  ="From:404 Bot - <$email>\n";
        		$text =
        "Seite: https://example.org$dateiname
        
        Quelle: $refere
        
        $useragent";
        		mail($email,"404 Bot",$text,$header);
          }
        ?>