PHP vs. C#
Teil 2: PHP vs C# .NET
Skriptsprache mit JIT Kompilierung oder Kompilierung mit Buildprozess
PHP ist eine Skriptsprache und führt Programmcode erst bei einem Request über HTTP aus. Alternativ läuft PHP auch mit PHP CLI über die Kommandozeile. Für PHP ist auf dem Endgerät also ein PHP Interpreter für das Betriebssystem erforderlich. Der Code kann ohne Rücksicht darauf programmiert werden.
C# ist normalerweise eine strikt typisierte und über einen Kompiler beim Aufruf zu einer Zwischensprache CIL unabhängig vom Betriebssystem kompiliert wird. Auf dem Zielsystem ist eine Runtime, .NET, erforderlich, um den CIL Code dann nochmals zu kompilieren. Das funktioniert genauso wie wie auch bei JAVA.
PHP braucht vorher nicht kompiliert werden. Änderungen funktionieren direkt. C# musste bislang schon vorher kompiliert werden. Änderungen funktionieren erst nach Kompiling und Deployment.
** NEU Microsoft hat für .NET ein neues System "Roslin" geschaffen mit dessen Hilfe man C# Code zur Laufzeit nachladen und kompilieren und ausführen kann. Das funktioniert ähnlich wie bei PHP und JS mit eval() Methoden, dh. man liest den Code als String.
Mit dem Verfahren ist es möglich, dass Teile eines C# Programms tatsächlich genauso wie bei C# "live" programmiert/geändert werden können. Alles, was man dafür machen muss, ist ein Objekt der zugehörigen Roslin-Klasse im Code zu referenzieren.
Jemand, der also Skriptsprachen wie PHP oder JS liebt, weil man ändert und es sofort vom Server übernommen wird, kann das damit auch in C# machen.
Wessen Programmcode ist auch im Browser lauffähig?
PHP läuft NICHT im Browser. C# bislang auch nicht.
NEU: C# läuft über 2 Ansätze im Browser: SSR und CSR Ansatz.
SSR: Serverside Rendering. Der für den Browser erforderliche HTML/CSS Code wird serverseitig erzeugt ähnlich wie man es in PHP machen würde. Man programmiert also quasi HTML Templates in Blazor oder Razor Syntax, verwendet als Skriptsprache aber C#. Ja, kann man auch JS adressieren und umgekehrt, aber der Code muss nach Änderungen kompiliert werden.
WASM WebAssembly: Hierbei wird der gesamte C# Code zu WASM kompiliert und läuft damit als vollständiger Client im Browser. Man kann für Komponenten entweder Razor Class Library Komonenten RCL nutzen, dh. für typische HTML Aspekte gibt es fertige C# Klassen. Der Entwickler braucht für diese Komponenten also eigentlich kein JS mehr wissen, wenn die Community für Problemstellungen schon Components hat.
Eigene Razor Components funktionieren wir PHP/HTML oder WebComponents/JS auch aus, nur eben läuft das komplett später im Client.
Wessen clientseitiger Code im Browser kann auch zur Laufzeit "live" kompiliert und ausgeführt werden?
NEU: Mit Roslin soll es für C# Info möglich sein, dass auch in diesem Fall Code mit eval() ausgeführter C# String Code in Echtzeit "live" kompiliert wird. Das gilt für Browser Apps, Apps und Desktop-Anwendungen. Hinweis: Es ist davon auszugehen, dass der Client aber ein paar mehr Byte haben wird [1] .
Wie steht es mit der Entwicklung eines Portalprojekts mit nicht nur User-Generated Content sondern auch dem Skripting von User-Funktionen beim Vergleich von PHP und C# für Webanwendungen?
Mit PHP wie WordPress sieht man, wie User / Kunden nicht nur eigene Templates als HTML und CSS und JS bauen können sondern auch PHP Code ergänzen können. So läuft in WordPress User-PHP Code mit einem Trick in einer Sandbox, indem man die GLOBALS löscht bevor deren Code ausgeführt wird. Wirklich 100% sicher ist das definitiv nicht, aber so kann man mit einer Installation mehrere Webseiten/Kunden verwalten.
Darüber hinaus lässt sich in PHP wie auch in JavaScript ein String/Text mit PHP-Code über beliebige Quellen zur Laufzeit einlesen und mit der eval() Funktion ausführen. Hinweis: Man sollte so etwas nicht machen, aber es funktioniert.
Damit User auch bei C# Anwendungen eigenen Code schreiben können, um beispielsweise eine Validierungsfunktion oder auch eine serverseitige Design-Template für die Umwandlung von <p> in <p class="bla"> programmieren können, gibt es nun 2 Varianten:
Rosling: Wenn nicht nur die Daten eines Users im Portal sondern auch Skript-Strings mit C# Code ebenso gespeichert und über Formulare übertragen werden auf den Server, kann .NET deren Code zur Laufzeit serverseitig ausführen. Wenn man also wie in WordPress vor machDas() ein machDasVorher(function) und machDasNachher(function) programmiert, hat man sogenannte "Hooks". WordPress arbeitet zu 99% nur so.
Sandboxing: Wie steht es um die IT-Sicherheit mit User-Skripts und damit Programmcode, welcher von Anwendern geschrieben und vom System automatisch ohne weitere Prüfung ausgeführt werden darf?
IT-Sicherheit: Die sicherere Variante ist die, dass dieser C# User Code nicht auf dem Server sondern erst im Client ausgeführt wird; damit ist es dessen Browser/App/PWA und auch dessen Rechenzeit.
IT-Sicherheit: Bei einer sicheren Varianten auf Serverseite empfielt die KI "Docker" Container und hat auch gleich Code gezeigt, wie man in C# .NET einen neuen Docker-Container zur Laufzeit als Sandbox erzeugen kann. So etwas erfordert zwar mehr Arbeitsspeicher, wäre aber eine Option.
Wie steht es um die SQL Datenbank-Anbindung und die Serialisierung objektorientierter Daten in XML und JSON?
PHP bietet Anbindung an MySQL sowie auch XML und JSON. Man muss aber alles von Hand bauen. Auch für PHP gibt es durchaus Open-Source-Frameworks für OR/M Techniken; diese stammen aber nicht von PHP selbst.
.NET bietet Entity Framework Core, kurz EF Core oder EFC. Hiermit ist es möglich, im Code-First-Ansatz eine C# Klasse so zu programmieren, dass nicht nur die zugehörigen Datenbank-Tabellen angelegt werden sondern das auch für Serialisierung in XML oder JSON funktioniert.
.NET bietet darüber hinaus über LINQ eine wie vereinfachtes SQL aussehende Abfragesprache mit welcher man Arrays, Collections, Datenbanken, XML und JSON in der SELBEN SYNTAX abfragen kann. Das bedeutet sinngemäß: Selbst Werte in Arrays lassen sich damit mit WHERE und GROUP Befehlen durchlaufen, Filtern und die Ergebnisse gruppieren.
Webserver unter Windows und Linux installieren, betreiben und Anwendungen installieren: Wie sieht's aus?
PHP nutzt zumeist Apache/PHP/MySQL. PHP läuft auch über Nginx/PHP/MySQL ohne Apache oder auch mit Apache. Windows oder Linux: Überhaupt kein Problem.
C# verwendet statt Apache den HTTP Server aus .NET Core, wobei es nur noch .NET heißt, dh. das Ding ist inzwischen komplett in .NET integriert, so dass man Core nicht mehr als Neuerung erwähnen muss. Wichtig: Das ist KEIN ASP.NET 4.x mehr sondern ASP.NET Core, was nur noch .NET heißt.
NEU: Seit dem Kauf des Mono-Projekts (.NET für Linux, Open-Source) durch Microsoft ist es möglich geworden, .NET Anwendungen auch unter Linux betreiben zu können. Die Installation unter Ubuntu ist heute nur noch ein 2-3 Zeiler da die Linux-Distributionen diese Runtimes kennen. Die Ausführung und sogar das Compiling von Code erfolgt über einen Konsolenbefehl "dotnet ....", ist also auch ein 1-Zeiler. Für einen Serverneustart ergänzt man sinnvoll das im Ladevorgang von Linux, sind gefühlt 3 Zeilen, KI ist Dein Freund.
Vergleich des Apache HTTP Servers für PHP mit .NET Core und C#
Auch wenn neuere PHP Versionen seit PHP 8.x einen eigenen internen HTTP Server bekommen und damit auch PHP selbst ohne Apache, Nginx und dergleichen einen HTTP(S) Server auf Port 80, 443 oder Wunschport laufen lassen kann, ist der Standard bislang Apache, zunehmend hinter einem Reverse Proxy wie Nginx.
Im Falle von .NET spricht man nicht mehr von .NET Framework oder .NET Core: Dieser HTTP Server ist inzwischen zentraler Bestandteil von .NET. Da man C# Code ohnehin kompilieren zieht man sich die zugehörigen Assemblies bzw. NuGet Paket für den HTTP Server in sein Projekt.
Mehrere Anwendungen auf dem selben HTTP(S) Port
Im Falle von PHP ist das entweder für den Apache Webserver mit .htaccess oder über den Reverse Proxy Nginx über dessen Konfigurationsfiles zu konfigurieren. Insbesondere der Nginx Server dient dazu, URL/URI basiert HTTP(S) Requests an auch parallel auf dem Server installierte HTTP Service und damit nicht nur PHP/Apache sondern auch JAVA, NodeJS oder C#/.NET zu routen.
Auch .NET kann HTTP Request auf dem selben Port anhand von URI /bla/bla unterscheiden und verschiedenen C# Programmen oder C# Klassen für die Antwort auf Requests routen. Das Routing erfolgt wahlweise über XML Files zur Konfiguration des .NET Core Servers. Es kann auch über URI-Strings im C# Code gemacht werden. Die Besonderheit hierbei: Man kann in C# auch Webservices ohne den .NET Core HTTP Server programmieren und verschiedene URLs und URIs hierbei beim selben HTTP Server Objekt registrieren. Dieses ermöglicht es, dass man in C# nicht Stand-Alone-Programme schreiben können die nicht im einem .NET Server deployed werden müssen sondern eigenständig bereits diese Funktionalität mitbringen.
Routing von HTTP(S) und anderen Requests unter Berücksichtung von HTTP Methoden wie GET, POST, erwartetem MIME Type für Results und mehr
Damit ein C# Programm in Abhängigkeit von HTTP GET oder POST oder Anfragen nach JSON oder JPG verschiedene Methoden der Klasse aufrufen kann, ergänzt man einfach Annotationen. Man schreibt also [POST] über eine MachWas() Methode. Wenn der User also /bla/ mit POST a=12 überträgt, routet .NET das an die Klasse. Dort erzeugt .NET dann ein Objekt dieser Service-Klasse, dh. wenn 100 Leute gleichzeitig zugreifen, erzeugt .NET eben 100 solche Objekte. Jedes Objekt verarbeitet dann eine Methode die Anfrage, und dann wird das Objekt wieder gelöscht.
Bislang musste bei einer Änderung des Skripts auf Serverseite C# neu kompiliert werden und ggf. auch der Server neu gestartet werden. Mit Roslin ist das aber für den Code, der als String geladen wird, nicht mehr erforderlich.
Synchronisation von Datenmodellen zwischen 100 Clients und einem Server in Echtzeit
Ein typisches Beispiel hierfür sind Chat-Systeme oder auch Online-Spiele. Es kann sich aber auch schlichtweg um eine klassische webbasierte Software handeln bei welche mehrer Anwender gleichzeitig z. B. Buchungen in einem Portal erzeugen und andere ggf. diese bestätigen. Das Prinzip: Ein User legt in Echtzeit ein Objekt hierbei zuerst einmal im Client/Browser/App an, und der Server soll das serverseitig speichern und sicherstellen, dass die anderen 99 gerade eingeloggten User das auch sehen.
PHP: Hier muss man sich zwingend serverseitig mit PHP und im Browser mit JS herumschlagen. Dafür sind die ganzen Frameworks mit Angular, ReactJS, Vue da. Man kann das auch dann mit JavaScript mit fetch() oder herkömmlichen "AJAX" Techniken programmieren. Was immer man auch macht: Selbst dann, wenn man ein Framework nutzt, kommt man im Regelfall mit PHP allein nicht mehr weiter.
C#: Alle diese 3 Frameworks wie Angular, ReactJS, Vue und mehr können bei C# auch verwendet werden, wenn man weiterhin HTML/CSS/JS Frontends will. Mit Blazor und RazorPages ist es bei .NET Core aber so, dass die auch komplett in C# geschrieben werden können (siehe oben). Wenn man also fertige sogenannte Blazor- und Razor-Komponenten findet oder sich die anderen für C#>JS/HTML baut, kann man zukünftig alles in C# bauen.
Beispiel: Wenn alle Daten in einem "Array" auf Server und im Client synchronisiert werden sollen muss also jede Veränderung bei 1 Client dem Server mitgeteilt werden der dann wiederum irgendwie alle die anderen 99 Clients informiert. Das Problem: Bei einer zustandslosen Verbindung bekommt ein Client die Informationen eigentlich erst, wenn der Client sich von sich aus beim Server meldet, denn normalerweise kann ein Server den Browser-Client von sich aus gar nicht adressieren weil zwischenzeitig der Browser nach seiner Anfrage die Verbindung gekappt hat.
Mit WebSockets ist es aber möglich, die Verbindung zwischen Client/JavaScript/Browser und dem Server aufrecht zu erhalten. Das Problem ist nur: Darauf ist wiederum PHP eigentlich nicht ausgelegt, denn auch PHP beendet nach einer Anfrage die Verbindung. PHP Programme werden also bei einem Aufruf in den Speicher geladen, ausgeführt und dann wieder beendet.
In C# für .NET Core basierte HTTP Services funktionieren etwas anders: Hier wird dem Server über die Konfiguration mitgeteilt, von welcher Klasse bei einem HTTP Request ein Objekt erzeugt werden soll welches dann diese Anfrage verarbeitet. Die Besonderheit im Unterschied zu PHP: Die C# Anwendung wird beim Serverstart bzw. beim ersten Aufruf also einmal in den Speicher geladen und kann deshalb weiterhin nachfolgende Anfragen verarbeiten. Das Objekt für die letzten Anfrage geht zwar nach der Antwort verloren; es ist aber möglich, dass dieses die Anfrage verarbeitende Objekt kurzerhand schlichtweg Informationen der letzten Anfrage in einer statischen Variable einer Klasse speichert, so dass zwar das Objekt für die Anfrage gelöscht wurde, die zugehörige Klasse aber weiterhin im Arbeitspeicher Daten zwischenspeichern kann, und zwar nicht ähnlich wie bei Sessions nur in Bezug auf einen bestimmten Nutzer sondern auch anwender übergreifend.
NEU: "SignalR". Diese Synchronisation von Datenmodellen lässt sich mit SignalR von Microsoft als .NET Komponente automatisieren. Man kann also den Client und auch die Serverseite in C# schreiben und muss dann sicherstellen, dass der Kompiler versteht, welche Daten synchronisiert werden müssen. Man kann sich also in C# faktisch mit SignalR dann Angular sparen.
Typisierung
C# ist eine strikt typisierte Programmiersprache, wobei man Variablen auch mit 'var' statt einer Typangabe deklarieren kann. Hierzu muss man allerdings wissen, dass der Datentyp hierbei basierend auf dem Datentyp des über '=' während der Initialisierung zugewiesenen Wertes bestimmt wird. Eine Variable in C# hat also stets nur einen Typ.
PHP unterstützt eine strikte Typisierung in PHP 7 und PHP 8 in Bezug auf die Definition von Parameter und Return-Werte von Methoden von Klassen. Dieser Ansatz ist allerdings optional. Darüberhinaus bietet PHP die Option, dass man als Entwickler auch zwei und mehr Datentypen angeben kann.
Variablen mit zwei und mehr Datentypen.
In PHP ist es auch bei strikter Typisierung von Methoden und Returnwerten in Klassen möglich, zwei und mehr Typen anzugeben. Der Sinn und Zweck hierbei dient darin, dass zur Laufzeit der PHP Interpreter schlichtweg, prüft, ob der Wert einem der genannten Typen entspricht.
Bei C# ist dieses Verfahren so nicht möglich bzw. so ählich wie bei C++ oder JAVA auch überhaupt nicht gewollt. Wer in C# für einen Parameter zwei Typen ermöglichen möchte muss den zugehörigen Wert entweder vom Basistyp "object" übertragen, einen Interface-Typ finden bzw. programmieren oder könnte sich auch mit Lambda-Expressions austoben.
Zusammenfassend
Mit Hilfe von C# als Programmiersprache ist es inzwischen möglich, nicht nur Einsatzbereiche, für die man einst JAVA verwendet hat, abzudecken, sondern auch Skripting-Techniken mit Compiling von geändertem Code "live" in Echtzeit sich in diesem Punkt wie eine herkömmliche Skriptsprache wie JS, PHP oder Perl zu verhalten.
Links, Quellen und Anmerkungen
Diese Seite, ist wie man sehen kann, noch im Aufbau. Rom wurde auch nicht an einem Tag gebaut.
Tags
Quellenangaben
UIO3 Es ist einfacher als Du denkst.
Stelle noch heute Deine Anfrage.
