Gerüst für Client-Server-Apps

 Richard Stallmann:

 Ich denke, dass jede allgemein nützliche Information frei sein sollte. 
 Mit 'frei' beziehe ich mich nicht auf den Preis, sondern auf die Freiheit, 
 Informationen zu kopieren und für die eigenen Zwecke anpassen zu können. 
 Wenn Informationen allgemein nützlich sind, wird die Menschheit durch ihre 
 Verbreitung wieder reicher, ganz egal, wer sie weitergibt und wer sie erhält.

Projekt-Kurzfassung Übersicht

Es ist ein einfaches und doch möglichst viefältig wiederverwendbares Gerüst für Client-Server-Apps zu entwickeln und zu testen.



Hinweise: Teste Online AJAX und Online

AJAX braucht Client und Server. AJAX braucht ein funktionstüchtiges Web. Notwendig fuer AJAX ist ein Online-Browser ( und/oder Node.js ). Es gibt Unterschiede, ob die aktuelle Seite eine *.htm online-Seite vom Web-Server ist oder eine lokale *.htm Datei ist. Der Online-Zustand kann abgefragt werden, wie z.B.

 function is_online() { 
   var p = document.URL; // var p = window.location.protocol;
   return ( /(http|https)\:/.test(p) ) && (!/file\:/.test(p)) ;
 }

Was meint synchron / asynchron ? Der Begriff "asynchrone Datenübertragung" ( zeichenweise asynchron ) darf nicht mit der Asynchronen Kommunikation verwechselt werden ( Abfolgen von Anfrage/Antwort bei Übertragungsprotokollen ).


Hinweise: AJAX - Schnellstart Einführendes

Welche Vorteile haben also asynchrone ( nicht-blockierenden ) Callback-Funktion gegenüber synchronen ( blockierenden ) Übertragungen? Wie kann AJAX ( Asynchronous JavaScript and XML ) als unvollständiger Anteil von Formular-Daten-Übertragungen durch den Browser gesehen werden? Siehe AJAX from Scratch ( Vergleich zwischen Formular und AJAX ) und ggf. ergänzend Lade HTML-Fragment mit AJAX


Wie geht das mit AJAX-Request/Response?

Zunächst wird das AJAX-ECMAScript-Objekt xhr = new XMLHttpRequest(); gebraucht, etwa wie folgt:

  var xhr;
  try { xhr = new XMLHttpRequest(); 
  } catch (failed) { xhr = false; }
  if (!(xhr && is_online())) { 
        alert("Senden unmöglich\nKein Internet/XMLHttpRequest"); 
  }

Wie geht das mit dem AJAX-Request ( senden, upload )?

xhr.open("POST", "my.php", true); 
xhr.setRequestHeader("Content-Type",
   "application/x-www-form-urlencoded; charset=UTF-8");
// xhr.setRequestHeader("Content-type", "application/json");
var vStr = verschluessele_str ( JSON.stringify( obj ) ) ;
var upload_str = MY_KEY1=' + MYSTR1 + "&MY_KEYv=" + vStr;

xhr.send( upload_str );

Wie geht das mit AJAX-Response ( Callback-Funktion )?

Hier lediglich ein vereinfachter Hinweis:

  xhr.onreadystatechange = function () {

    if (xhr.readyState === 4 && xhr.status === 200) 
    {
      alert( xhr.responseText ); 
      // oder that.form.MYNAME.value = xhr.responseText;
    }
  };
 //was dann? if (o.post_reset) {that.form.reset(); }
 //was dann? if (o.post_htm) { bib.url_to_frame(o.frame_name, obj.urlpost); }

upload_str = "MY_KEY1=" + MYSTR1 + "&MY_KEYv="+upload_str; wird mit dem Request xhr.send(upload_str) an my.php gesendet.

php verwendet für die response-Antwort die echo-Funktion. Infolge der php-Antwort(response) wird die Browser-Callback-Funktion xhr.onreadystatechange = function () {...) aufgerufen. Der Antwort-String xhr.responseText stammt von der php-echo-Funktion.


Hinweis: "auto"-Namen ( client/server ) Namesgleichheit

Werden z.B. Server-Verarbeitungen und Server-Verzeichnisse erzeugt/verschoben, so ist durchgängig eine gleiche Namenswahl, wie my_app.htm ( clientseitig ) und my_app.php ( serverseitig ) besonder günstig.

Warum? Wird z.B. bei einer Erweiterung ein weiteres clientseitig/serverseitig Paar wie
my_app1.htm ( clientseitig ) und
my_app1.php ( serverseitig ) gebraucht, so kann ( clientseitig ) my_app1.htm mit Hilfe von url_php_von_url_html() den benötigten neuen .php-Namen leicht ermitteln.

 function auto_php_url() { "use strict";
  var auto_url = document.URL;
  if(!(/.+\.php/).test(auto_url)){ 
    auto_url = auto_url.slice(0, 
	           auto_url.lastIndexOf(".")) + ".php"; 
  } return auto_url;
 }

Hinweise: Baue JSON-upload-String Kannst du upload?

In my_app.htm ( clientseitig ) ist eine Funktion baue_json_upload_str() sinnvoll, die in

 obj = { dst: auto_php_url(), 
         myId: "DL1", 
		 myStr: "äöü", 
		 myArr: [1,2,3] };

alle Daten zusammen stellt, und mit json_send_str = JSON.stringify(obj) die zum Server übertragen werden sollen.

Das clientseitige obj sollte auch "Überschüssige" Daten enthalten, die nach dem upload auf dem Server zu "white-Sicherheitsprüfungen" dienen können.


Hinweise: PHP-debuggen PHP-Funktionen

Es gibt Entwicklungsumgebungen, die auch das Debuggen von PHP-Quelltexten ermöglichen. Einfache Möglichkeiten bietet PHP, wie z.B.

var_dump($arr) dient der debug-Anzeige mit typ-Angabe der Member
print_r($arr) dient der debug-Anzeige ohne typ-Angabe der Member
var_export($arr) liefert gültigen php-Code,
kann aber keine reference, keine cycles/recursive arrays,
wie z.B. var_export($_GLOBALS);

Achtung! PHP-Keywords, Classes, Functions und user-definierte Functions sind ggf. NICHT case-sensitive.

PHP-Beispiele

 phpInfo();                           // zeigt u.a. Installationsinfos an

 print_r( get_defined_functions() );  // zeigt u.a. die verfügbaren Funktionsnamen an

 foreach (getallheaders() as $name => $value) {
    echo "$name: $value\n";
 }

 
 
 function get_php_url() { 
   $temp = 'http'.(isset($_SERVER['HTTPS'])?'s':'').'://';
   return "$temp{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
 }
 
 function get_dir_name() {
  return dirname(get_php_url());
  }

 function get_anz_files_in_dir() { 
   return count($files = scandir(__DIR__)); 
 }

Zu PHP (Version...) gehören eigebauten Funktionen


Hinweise: Verwendung von XAMPP-PHP-Installation PHP-debuggen?

Laufen .htm ( Client ) und .php ( Server ) beide auf einem Computer, so wird ein Entwickeln von PHP-Code Vorteile/Nachteile haben ( Sicherheit, www-url-file-"Salat", schnelles Testen, usw. ). Z.B. bei clientseitiger XAMPP-PHP-Installation ist der Zusammenhang zwischen der
Netz-URL http://localhost/ und dem
File-Pfad im Dateisystem zu klären! Läuft z.B. XAMPP clientseitig, so liefert die folgende Funktion Hinweise zur aktuellen url.

  function get_url_parts(){ 
   var a = document.createElement("a");
       a.href = document.URL;
   var obj = {
    url: document.URL,
    protocol: a.protocol, // "http:"
    hostname: a.hostname, // "example.com"
    pathname: a.pathname, // "/pathname/"
    search: a.search,     // "?search=test"
    hash: a.hash,         // "#hash"
    host: a.host,         // "example.com:3000"
    port: a.port          // "3000"
  }; return obj;
 }
 // übersichtliche Anzeige mit 
 console.log(
    JSON.stringify( get_url_parts() )
        .replace(/","/g, '",\n"')
 );

Hinweise: PHP-Strings Zeichenkette === String?

Hinweise in der Veranstaltung.

Was ist ein String? Zu Programmiersprachen und Betriesbssystemen gehören Stringdarstellungen ( angepaßte, native ). Ein ECMAScript-String ( Quelltext ) ist nicht identisch zu einem PHP-String. PHP-Strings sind verschieden von ECMAScript-Strings. Beispiele:

Ein ' ' - PHP - String wird nicht geparst. Z.B. entspricht ein 
          PHP-String         ' $fn \n'    dem 
          ECMAScript-String  ' $fn \\n'   und dem
          ECMAScript-String  " $fn \\n"

Ein " " - PHP - String wird geparst, d.h. 
          bei " $fn \n"  wird die PHP-Variable $fn eingesetzt 
          und aus \n wird der Zeilen-Umbruch-Code 10. 

  PHP                                  |  ECMAScript
----------------------------------------|----------------------------------------
  $str1 = 'abc';                        |  var str1 =  'abc';
                                       | 
  $str2 .= 'UVW' . "XYZ";               |  var str2 += 'UVW' + "XYZ";
                                       | 
  $arr = array("a","b","c");            |  var arr = ["a","b","c"]; 
                                       | 
  $str = implode("-", $arr);            |  var str = arr.join("-");


  PHP Associative Arrays               | ECMAScript-Objekte
----------------------------------------|----------------------------------------
  $arr = array (                        | var obj = { 
        "obst"  => array(               |            "obst" : { 
                   "b" => "Birne",      |                    "b" : "Birne",
                   "c" => "Apfel"       |                    "c" : "Apfel"
                   )                   |                     }
        );                             |           };

----------------------------------------|----------------------------------------
  $arr = json_decode( $json_str,true ); | var obj = JSON.parse(json_str);
                                       |               
  $json_str = json_encode( $arr );      | var json_str = JSON.stringify(ob);

Teste:

<?php
$json_str = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json_str));
var_dump(json_decode($json_str, true));
?>

<script>
var json_str = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var obj = JSON.parse($json_str);
alert( "obj.a=" + obj.a  );
alert( " Object.keys(obj) liefert arr = " + Object.keys(obj) );
</script>


Konvertiere Unicode wie etwa U+597D nach HTML entity: ungeprüft:
$utf8str = html_entity_decode(preg_replace("/U\+([0-9A-F]{4})/","&#x\\1;",$str),ENT_NOQUOTES,'UTF-8');
          mb_convert_encoding(preg_replace("/U\+([0-9A-F]*)/","&#x\\1;",$str),"UTF-8","HTML-ENTITIES");

Weblinks: Einführung bei php.net in das Arbeiten mit PHP-Strings ,
www.w3schools PHP-Strings , PHP-String-Funktionen php.net

Plagiate sind out!
Viel Freude bei der Ausarbeitung!
Letzter Abgabetermine So 12.00 Uhr