WebClient PHP aufrufen

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von EugenIS.

    WebClient PHP aufrufen

    Hallo Leute und danke für's reinschauen.

    Kennt jemand eine Möglichkeit ein PHP Script per WebClient auszuführen mit Übergabewerten sowie Rückgabewert?

    Hier der Beispiel klappt, aber nur begrenzt...:

    C#-Quellcode

    1. public async static Task<object> SendToServerJson(string path, string param)
    2. {
    3. try
    4. {
    5. var webClient = new WebClient() { Encoding = Encoding.UTF8 };
    6. webClient.Headers[HttpRequestHeader.ContentType] = "application/json";
    7. webClient.Encoding = Encoding.UTF8;
    8. return await webClient.UploadStringTaskAsync(string.Format("{0}{1}", wmGetServer(), path), param);
    9. }
    10. catch (Exception ex)
    11. {
    12. return null;
    13. }
    14. }


    Die PHP wird ausgeführt. Wie rufe ich aber eine Methode auf mit einem Übergabewert und wie erhalte ich was zurück?

    Danke im Voraus.

    *Topic verschoben*

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Hey,

    Probier mal mit WebClient.UploadValues

    C#-Quellcode

    1. class Program
    2. {
    3. static void Main(string[] args)
    4. {
    5. Task.Run(async () =>
    6. {
    7. Console.WriteLine(await SendJsonToServer("data"));
    8. });
    9. Console.ReadLine();
    10. }
    11. static async Task<string> SendJsonToServer(string json)
    12. {
    13. using (WebClient wC = new WebClient() { Proxy = null })
    14. {
    15. NameValueCollection data = new NameValueCollection()
    16. {
    17. { "data", json }
    18. };
    19. try
    20. {
    21. return Encoding.UTF8.GetString(await (wC.UploadValuesTaskAsync("http://localhost:8000/test.php", "POST", data)));
    22. }
    23. catch (Exception)
    24. {
    25. return "Upload failed.";
    26. }
    27. }
    28. }
    29. }
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Nein, das hilft mir nicht weiter. Die PHP wird ausgeführt auch mit meinem Code. Mir gehts darum eine bestimmte Methode aufzurufen, ihr Parameter zu übergeben und einen Rückgabe-wert zu erhalten.

    Und was genau sollen die ganzen Sprüche? Kein Bock zu helfen, lass es doch. Niemand ist zu was gezwungen!

    EugenIS schrieb:

    Und was genau sollen die ganzen Sprüche?
    Bissel aggro heute morgen? Welche Sprüche denn? Wenn es um das mit der Unendlichkeit und dem Pech beim Denken geht, dann sind das Teil seiner Signatur. Die stehen bei jedem Post von SpaceyX automatisch mit dabei und haben nix mit Dir zu tun.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Oh, dann hab ich Dein Problem missverstanden. Ich war auf eine andere Thematik fixiert. Erläutere bitte mal ein bisschen genauer, was Du überhaupt erreichen möchtest.

    P. S. Über Deine unfreundliche Antwort sehe ich jetzt mal hinweg....
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Ich hoffe, ich hab nun Dein Problem richtig verstanden. Du willst eine PHP-Funktion aufrufen und deren Rückgabewert in Deinem Programm verarbeiten. Richtig? Wenn ja, hier mein Lösungsvorschlag. Mit PHP hab ich nicht wirklich viel am Hut und hab da nur rudimentäre Kenntnisse.

    PHP-Quellcode

    1. <?php
    2. if(!isset($_POST['fName']) || !isset($_POST['fParam'])) {
    3. echo ("Invalid request");
    4. exit();
    5. }
    6. $fName = $_POST['fName'];
    7. $fParam = $_POST['fParam'];
    8. try {
    9. echo(call_user_func($fName, $fParam));
    10. } catch(Exception $e) {
    11. echo("Function-Call failed");
    12. exit();
    13. }
    14. function AppendString($param) {
    15. return $param.".append";
    16. }
    17. function AppendInt($param) {
    18. return $param.".123";
    19. }


    Und hier das überarbeitete C# Programm

    C#-Quellcode

    1. class Program
    2. {
    3. static void Main(string[] args)
    4. {
    5. Task.Run(async () =>
    6. {
    7. Console.WriteLine(await SendJsonToServer("data"));
    8. });
    9. Console.ReadLine();
    10. }
    11. static async Task<string> SendJsonToServer(string param)
    12. {
    13. using (WebClient wC = new WebClient() { Proxy = null })
    14. {
    15. NameValueCollection data = new NameValueCollection()
    16. {
    17. { "fName", "AppendInt" },
    18. { "fParam", param }
    19. };
    20. try
    21. {
    22. return Encoding.UTF8.GetString(await (wC.UploadValuesTaskAsync("http://localhost:8000/test.php", "POST", data)));
    23. }
    24. catch (Exception)
    25. {
    26. return "Upload failed.";
    27. }
    28. }
    29. }
    30. }


    Du übergibst in Deinem Post-Request, zusammen mit den Parametern, den Namen der Funktion, die vom PHP-Skript ausgeführt werden soll. Die PHP-Funktion call_user_func kümmert sich dann um den Rest.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Schöne Remote Code Execution Sicherheitslücke.

    Alles was man in der Programmierung von extern übergeben bekommt, muss man valideren.
    Beim Lösungsansatz von @SpaceyX wäre

    PHP-Quellcode

    1. if(!in_array($fName, [ 'AppendString', 'AppendInt' ])) { die(); }

    ein entsprechender Anfang.

    Unter dem Begriff "Routing" sollte man zur Ausgangsfrage im Internet auch gut etwas finden können.
    @VaporiZed bin nicht agro. Es ist doch mein gutes Recht meine Meinung zu den Sprüchen zu sagen, auch wenn die nicht zu mir gemeint waren. Es mag sein, dass anderweitig die Sprüche sehr ankommen würden. Dennoch darf ich vielleicht manch einen daran erinnern, dass dies hier ein Forum ist, wo sich Programmier-interessierte austauschen MIT UNTERSCHIEDLICHEN Kenntnisstand. Daher kommen die Sprüche etwas arrogant rüber so als ob nur die Experten berechtigt sind ihre Fragen hier zu stellen, wobei in dem Fall die gesamte Existenzberechtigung des Forums in Frage gestellt wird... Aber wie gesagt, es ist meine Meinung, die muss ja mit DEINER nicht wirklich übereinstimmen.

    @SpaceyX Du bist auf dem richtigen Weg, aber überliest eine Kleinigkeit: Methode... Nicht eine ganze Datei. Ich möchte eine Methode aufrufen:

    Quellcode

    1. EugenTest([IchGebeWasMit])
    2. {
    3. blablalba
    4. return "[IchErhalteWas]"
    5. }


    So ähnlich wie bei C#. Wobei eigentlich müsste ich korrekterweise Funktion heißen, weil Methode hat kein Rückgabewert. Es ist durch aus möglich, dass mehrere Methoden/Funktionen in einer PHP sind, die ich dann einzeln nach Bedarf aufrufen will...

    *CodeTag eingefügt - Bitte auch bei Pseudocode die Codetags verwenden* ~NoFear23m

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Nofear23m“ ()

    Hey,

    nun da bist Du, wie schon von @3daycliff erwähnt, bei Routing angekommen....

    PHP-Quellcode

    1. <?php
    2. if($_SERVER['REQUEST_METHOD'] != 'POST' || !isset($_POST['fParams'])) {
    3. echo ('Invalid request');
    4. die();
    5. }
    6. $request = strtolower($_SERVER['REQUEST_URI']);
    7. $fParams = json_decode($_POST['fParams']);
    8. switch($request) {
    9. case '/':
    10. echo('Welcome');
    11. break;
    12. case '/radtodeg':
    13. echo(RadToDeg($fParams));
    14. break;
    15. case '/pointdistance':
    16. echo(PointDistance($fParams));
    17. break;
    18. case '/hashvalue':
    19. echo(HashValue($fParams));
    20. break;
    21. default:
    22. echo('Invalid route');
    23. break;
    24. }
    25. die();
    26. function RadToDeg($fParams) {
    27. if(!CheckParams($fParams, 1, array('n'))) {
    28. die();
    29. }
    30. $deg = doubleval($fParams->params[0]);
    31. return $deg * 180 / pi();
    32. }
    33. function PointDistance($fParams) {
    34. if(!CheckParams($fParams, 4, array('n', 'n', 'n', 'n'))) {
    35. die();
    36. }
    37. $x1 = doubleval($fParams->params[0]);
    38. $y1 = doubleval($fParams->params[1]);
    39. $x2 = doubleval($fParams->params[2]);
    40. $y2 = doubleval($fParams->params[3]);
    41. return sqrt(pow($x2 - $x1, 2) + pow($y2 - $y1, 2));
    42. }
    43. function HashValue($fParams) {
    44. if(!CheckParams($fParams, 1, array('a'))) {
    45. die();
    46. }
    47. return hash('SHA256', $fParams->params[0]);
    48. }
    49. function CheckParams($fParams, $required, $dataTypes) {
    50. if (count($fParams->params) != $required) {
    51. echo ('Invalid parameter count');
    52. return false;
    53. }
    54. for($i = 0; $i < $required; $i++) {
    55. $dataType = $dataTypes[$i];
    56. if($dataType == 'n') {
    57. if(!is_numeric($fParams->params[$i])) {
    58. echo ('Paramter '.($i + 1).' is invalid');
    59. return false;
    60. }
    61. }
    62. }
    63. return true;
    64. }


    Dies ist eine extrem vereinfachte Form von Routing. Ich muss auch gestehen, dies ist nicht gerade mein Spezialgebiet und es steckt da weit mehr dahinter. Wie auch schon erwähnt, müssen die Inputs, die von außen kommen, gründlich validiert werden. Dies habe ich auch nur rudimentär gemacht.

    $_SERVER['REQUEST_URI'] beinhaltet den Pfad, der angefordert wurde. Um diesen dreht sich das Ganze. Im Switch-Statement wird nun geprüft, um welche Route es sich handelt und entsprechend die dazugehörige Funktion ausgeführt. Ist im Switch-Statement die Route nicht behandelt, so gilt sie ungültig und das Skript bricht ab.

    Die entsprechenden Funktionen kümmern sich um die Prüfung der Parameter (Stimmt die Anzahl, stimmen die Datentypen etc...). Genau hier muss genau geprüft werden, was ich aber nur auf die Schnelle gemacht habe. Liefert die Funktion CheckParams True zurück, so wird die angeforderte Funktion ausgeführt, ansonsten bricht das Skript ab, liefert aber noch einen Grund zurück.

    Anwenden kann man dies nun so:

    C#-Quellcode

    1. using System;
    2. using System.Net;
    3. using System.Threading.Tasks;
    4. using System.Text;
    5. using System.Collections.Specialized;
    6. using System.Collections.Generic;
    7. using System.Text.Json;
    8. using CoreLib;
    9. namespace ConsoleApp54
    10. {
    11. class Program
    12. {
    13. static void Main(string[] args)
    14. {
    15. Task.Run(async () =>
    16. {
    17. Dictionary<string, string[]> parameter = new Dictionary<string, string[]>()
    18. {
    19. { "params", new string[] { "14", "19", "105", "14.333" } }
    20. };
    21. Console.WriteLine(await SendJsonToServer(JsonSerializer.Serialize(parameter)));
    22. });
    23. Console.ReadLine();
    24. }
    25. static async Task<string> SendJsonToServer(string parameter)
    26. {
    27. using (WebClient wC = new WebClient() { Proxy = null })
    28. {
    29. NameValueCollection data = new NameValueCollection()
    30. {
    31. { "fParams", parameter }
    32. };
    33. try
    34. {
    35. return Encoding.UTF8.GetString(await (wC.UploadValuesTaskAsync("http://localhost:8000/PointDistance", "POST", data)));
    36. }
    37. catch (Exception)
    38. {
    39. return "Upload failed.";
    40. }
    41. }
    42. }
    43. }
    44. }


    Die Parameter werden als JSON-String an das PHP-Skript gesendet. Die Adresse kann nun entsprechend dem Funktionsnamen auf PHP-Seite gewählt werden, solange diese dort als gültige Route vorliegt und implementiert ist. Die soll nur eine Anregung sein, das Thema Routing ist weitaus komplexer...
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    @SpaceyX hab es ausprobiert.

    es scheint schon fast zu gehen. Das einzige Problem ist, dass ich die "NameValueCollection" nicht verwenden kann, weil es sich in System.dll befindet.

    Um der Frage zu entgehen, warum kann ich es nicht verwenden:
    Ich schreibe gerade eine Webseite mit C# und WPF. Sicherlich wirst du dich sehr berechtigt fragen, seit wann geht den das...
    Ich habe das hier gefunden: cshtml5.com/
    Funktioniert ganz gut, mit kleinen Einschränkungen wie z. B.: System.dll darf nicht verwendet werden... Also es dürfen so ziemlich gar keine DLL's eingebunden werden die das Tool nicht kennt. Paar Kinderkrankheiten gibt es auch... Manchmal wird bei der Darstellung ein wenig falsch interpretiert. Sonst kann ich nur gutes drüber sagen. Mit paar Tricks geht recht viel, wenn man bedenkt, das man mit Webentwicklung so ziemlich überhaupt keine Erfahrung hat.

    Wie dem auch sei, kann man die Parameter irgend wie manuel ohne NameValueCollection übergeben? So eine Json Datei sieht doch irgend wie so aus:

    Quellcode

    1. {
    2. fParams
    3. [
    4. "14",
    5. "19",
    6. "105",
    7. "14.333"
    8. ]
    9. }


    Es hat noch nicht ganz geklappt, werde morgen eventuell noch mal probieren. Jedenfalls konnte ich schon mal zu mindestens verschiedene Methoden bei der PHP Datei aufrufen, ohne Parameter.

    *Und nochmals @EugenIS, bitte verwende doch CodeTags. Danke* ~NoFear23m

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Nofear23m“ ()