Avatar billede vivaa.dk Nybegynder
18. oktober 2007 - 12:12 Der er 47 kommentarer og
1 løsning

Fra c# til php og MySQL med Soap

Hej

Jeg har udviklet et databasebaseret program, men har fået det problem at jeg ikke kan tilgå SQL fra remote connections.

En kollega har nu fortalt mig at jeg kan bruge en webservice kaldet SOAP.

Jeg har udviklet programmet objektorienteret og lagdelt. Så jeg har en klasse der indeholder alle kald mellem programmet og databasen.

Denne dataklasse vil jeg gerne have kodet om, så den istedet sender data med soap til et phpscript på serveren der derefter udfører de ting til databasen som skal klares.

Jeg vil ikke sidde her på eksperten og bede jer kode hele mit program om.

Men jeg vil gerne guides igennem at lave et lille miniprogram der opretter et element i en database, kalder nogle data fra databasen og udføre en update og en slet.

Så kan jeg altid selv rette program til når jeg har lært hvordan det fungere.

Håber der sidder en derude der har lyst til at guide mig igennem dette :)
Avatar billede nielle Nybegynder
18. oktober 2007 - 12:31 #1
Det lyder mere som om at det er i PHP enden at du skal lave din webservice. C# bliver nødt til at have noget den kan kalde (webservicen) for at det kan lade sig gøre.

Du behøver dog ikke at kaste dig ud i websrvise løsninger - det kan (nok) også gøres ved en almindelig form-baseret løsning, hvir dit C# program så at sige submitter til en form på din PHP side.

PS: SOAP er ikke en webservice - det er en XML baseret protokol som bl.a. bruges af webservices.
Avatar billede vivaa.dk Nybegynder
18. oktober 2007 - 12:40 #2
Ja mente egentlig også protokol :)

Men hvis kan det gøres sikkert nok hvis man submitter til en form?
Det skal være så sikkert som nu muligt.
Avatar billede vivaa.dk Nybegynder
18. oktober 2007 - 12:46 #3
Men en form kan vel ikke hente data ned? Den kan da kun oprette?
Avatar billede nielle Nybegynder
18. oktober 2007 - 14:24 #4
Det er klart at en webservice ville være ideelt til formålet. Men den skulle så oprettes i PHP. Jeg har ingen ide om dette er nemt eller svært, men det ville så nok være medst at flytte spørgsmålet til PHP kategorien.

Sikkert - det afhænger af hvad du mener med sikkert. Løsningen bliver ikke automatisk sikker fordi at det foregår via en WS. En mulig måde at beskytte sig på er ved at lade det gå via SSL og så skal der formentligt noget login på.

En FORM løsning ligger sig selbfølgelig mest op af at der sendes data, men du kan jo sagtens lave en side som viser data (altså et udtræk) ud fra givne søgekriterier. I C# kan du så tygge dig igennem HTML koden på denne side og omsætte det til C# variable - det kaldes for "screenscraping".
Avatar billede vivaa.dk Nybegynder
18. oktober 2007 - 14:27 #5
Men det er vel ligeså meget c# som det er PHP.

Der skal jo også kodes noget i c# der kan snakke samen med det..
Avatar billede nielle Nybegynder
18. oktober 2007 - 14:37 #6
Ja, men løsningen må nødvendigvis starte i PHP enden hvis det er en webservice.
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 10:35 #7
Har nogenlunde styr på at udvikle det i PHP..

Jeg har ihvertfald fået hentet det SOAP lib der skal bruges og set et eksempel på en PHP Soap server.

Men jeg kan overhovedet ikke finde en god beskrivelse af hvordan man laver en SOAP klient i c#.. :S
Avatar billede md_craig Nybegynder
22. oktober 2007 - 13:04 #8
Man tilføjer en Web Reference i sit projekt :P...
Og så nemt er det (næsten)...

det vil dog sige meget afhængigt af det data der skal sendes...
Har du nogle Business/Domain Objecter du ønsker at sende frem og tilbage med referancer til andre object ect. ect. kan det hurtigt blive ganske advanceret... er det derimod simple dataHolder klasser du vil transportere eller endnu simplere datatyper som int, string ect. så er det ganske overkommeligt...

alternativt kan du kigge her:
http://www.codeproject.com/Purgatory/Consume_WebService.asp
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 13:16 #9
Oki.. Men jeg kan ikke rigtigt finde den reference jeg skal tilføje :S
Hvad er det helt nøjagtigt jeg skal tilføje?

Jeg har en dataklasse i mit system jeg gerne vil erstatte med kommunikationen mellem klienten og serveren. Og den dataklasse adder selv til mine collection klasser, hvor de skal bruges, så hvis jeg fx kan sende et postnr ind i databasen og få en array af brugere retur er det fint nok.

Når jeg adder noget skal jeg bare kunne smide flere forskellige varibler ind, fx string, string, int, datetime osv.  Det kan vel godt gøres rimelig simpelt?
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 13:17 #10
Ved ikke om det har noget at sige, men det er bare en c# applikation jeg kører som klient.. Ikke et ASP.NET site..
Avatar billede md_craig Nybegynder
22. oktober 2007 - 13:25 #11
Principielt set der hvor din service ligger... et eksempel kan fx være:

http://www.webservicex.net/length.asmx

som er addressen til en Længde Enheds Converter Web Service.
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 13:49 #12
Ok.. Det vil sige at jeg godt kan lave en reference til den PHP fil på serverne der indeholder de metoder som jeg skal kalde?
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 14:35 #13
Har prøvet at implementere:

http://localhost/lib/nusoap.php

Men den skriver:

HTML-dokumentet indeholder ikke Discovery-oplysninger om webtjenester.
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 14:47 #14
ahh nu fik jeg den added..

Men den skriver når jeg prøver at køre programmet med en funktion:

Klienten opdagede, at svarets indholdstype var 'text/html', men forventede 'text/xml'.
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 14:50 #15
Har brugt ekemplet fra:

http://www.codewalkers.com/c/a/Miscellaneous/Using-SOAP-with-PHP/3/

til at lave serveren med.. det ser ud til at den danner et HTML dokument istedet for xml.. :S
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 15:10 #16
ahh doh nu kører det :)
Havde glemt at sætte mysql connection op..

Men hvordan får det jeg afsikret, så det kun et mit program der kan bruge soapserveren? Der skulle jo gerne være lukket af for tilgang udefra..
Avatar billede md_craig Nybegynder
22. oktober 2007 - 15:55 #17
Der må jeg desvære mælde pas... har ikke arbejdet meget med WebServices... så har jeg ikke kendskab til. og slet ikke hvis det ikke er dig der kører serveren selv...

men prøv at bladre rundt på google efter noget (PHP?) Web Service Permissions måske?
Avatar billede nielle Nybegynder
22. oktober 2007 - 16:01 #18
Fandt dette link:

http://beyrent.net/2005/11/03/php-and-soap-authentication/

I C# enden er det simpelt nok; her kaster du bare en Credentials på din webservice-proxy.
Avatar billede nielle Nybegynder
22. oktober 2007 - 16:06 #19
wsRef.Credentials = new System.Net.NetworkCredential(userName, password)
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 16:19 #20
Ok.. men hvad skal jeg placere her:

// Handle your authentication code here.  I use a MySQL database for holding user data

Forstår ikke helt hvordan jeg skal stille det op..
Avatar billede nielle Nybegynder
22. oktober 2007 - 18:36 #21
For lige at få koden på plads - der er4 en den "sjove" HTML-koder hist og her. Den skulle nok se sådan her ud:

<?php
class MySoapServer extends soap_server
{
    var $_objParser;

    // Class constructor
    function MySoapServer($wsdl=false)
    {
        // Create a new instance of the XML parser
        $this->_objParser = new MyXMLParser();

        // Call the parent constructor method and pass the WSDL flag to it
        parent::soap_server($wsdl);
    } // End Function

    function service($data)
    {
        // Parse the xml message
        $this->_objParser->setXMLData($data);

        // Retrieve the authentication information from the xml message
        $arrCredentials = $this->_objParser->getCredentials();

        // Sanity check - did we get the credentials?
        if (is_array($arrCredentials) &&
            ($arrCredentials["username"] != "") &&
            ($arrCredentials["password"] != ""))
        {
            // Authenticate the user
            $this->_intWSUserID = $this->_authenticate($arrCredentials);

            // If authentication was successful, handle the rest of the message
            if ($this->_intWSUserID > 0)
            {
                parent::service($data);
            }
            else
            {
                // return a SOAP fault
            }
        }
    } // End Function

    function _authenticate($arrCredentials)
    {
        // Sanity check: did we get a valid array?
        if (! is_array($arrCredentials))
        {
            // return a SOAP fault
        }

        // Handle your authentication code here.  I use a MySQL database for holding user data
    } // End Function
} // End of Class
?>
Avatar billede nielle Nybegynder
22. oktober 2007 - 18:51 #22
Dernæst til _authenticate() funktionen:

function _authenticate($arrCredentials)

Denne modtager et PHP array med login-informationerne - et array med credentials. Den helt simple implementering af denne ville være at hardkode tjekket ind:

    function _authenticate($arrCredentials)
    {
        // Sanity check: did we get a valid array?
        if (! is_array($arrCredentials))
        {
            // return a SOAP fault
        }
        else if ($arrCredentials["username"] != "vivaa.dk" ||
            $arrCredentials["password"] != "hemmelgt")
        {
            // return a SOAP fault
        }
        else
        {
            return 1;  // Jeg har ikke noget bedre bud.
        }
    } // End Function

Han nævner selv at han bruger en database. Det er til hvis han ønsker at kunne styre login-informationerne derfra i stedet for at hardcode dem ind i PHP scriptet. En sådan stumpr kode ville simpelthen ligne et almindeligt loginscript skrevet i PHP og baseret på f.eks. MySQL.

PS: Jeg har ikke lige nogen ide om hvad det betyder at "returnere en SOAP fejl". Det må stå nærmere beskrevet i NuSOAP dokumentationen.

PPS: Dette spørgsmål er som sagt mere et PHP spørgsmål end et C# ditto...
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 20:02 #23
det er også fint nok :)
Har dog fået et problem med at køre soap på mit webhotel :S

Jeg kørte det på min laptop før, der kører WAMP server, uden problemer..

Nu sidder jeg ved min stationære PC der kører XAMMP og får følgene fejl:
Fatal error: Cannot redeclare class soapclient in /mounted-storage/home26b/sub002/sc24152-ERZJ/Ole/soap/lib/nusoap.php on line 7240

Og smider jeg det op på webhotellet får jeg samme fejl :S

Ved godt at mit spørgsmål er besvaret, men hvis i lige har et hurtigt bud på det ville det være super :)

Mit forslag er at Nielle får 150 point og mr_craig får 50 points, kan det accepteres? :)
Avatar billede nielle Nybegynder
22. oktober 2007 - 20:41 #24
Din fejl lyder som om at du forsøger at inkludere PHP filerne med SOAL klassen mere end en gang.

I stedet for at bruge include() så prøv at bruge include_once() i stedet.
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 20:48 #25
Det var en gammel fejl i SOAP.. man skulle bare rette alle filer til, så der stod soapclientw istedet for soapclient.. Så virker det :)

Ved i hvordan man returnerer et array?

Takker for hjælpen..
Smid svar for points.. :)
Avatar billede nielle Nybegynder
22. oktober 2007 - 21:06 #26
Hvordan man returnere et array - i hvilken sammenhæng?
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 21:11 #27
Altså hvis jeg nu gerne vil indlæse et array af brugere til min klient fra databasen.
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 21:15 #28
Jeg har denne kode der returnerer et brugernavn:

<?php
function getBruger($id) {

    mysql_connect('localhost','root','');
    mysql_select_db('test');
    $query = "SELECT brugernavn FROM users "
          . "WHERE brugerid = '$id'";
    $result = mysql_query($query);

    $row = mysql_fetch_assoc($result);
    return $row['brugernavn'];
}

require('../lib/nusoap.php');

$server = new soap_server();

$server->configureWSDL('cmrServer', 'urn:bruger');

$server->register("getBruger",
                array('id' => 'xsd:int'),
                array('return' => 'xsd:string'),
                'urn:bruger',
                'urn:bruger#getBruger');

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA)
                      ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>
Avatar billede nielle Nybegynder
22. oktober 2007 - 21:21 #29
Sådan?

function getBruger($id) {
    mysql_connect('localhost','root','');
    mysql_select_db('test');
    $query = "SELECT brugernavn FROM users WHERE brugerid = '$id'";
    $result = mysql_query($query);   

    $brugernavnArr = array();

    while ($row = mysql_fetch_assoc($result)) }
        $brugernavnArr[] = $row['brugernavn'];
    }

    return $brugernavnArr;
}
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 21:35 #30
har sat:

$server->register("getBrugere",
                array('return' => 'xsd:array'),
                'urn:bruger',
                'urn:bruger#getBrugere');

Men den skriver:

http://ole.vivaa.dk/soap/test/index.php?wsdl
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 21:48 #31
hov var ikke det jeg ville kopiere ind :)

Men anyways.. Kan ikke rigtigt finde ud af at trække et array ind, så den kan læse det i c# :S
Avatar billede nielle Nybegynder
22. oktober 2007 - 21:49 #32
Nu er jeg ikke selv bekendt med NuSOAP så jeg må selv browse mig frem til hvad der kunne være galt:

1) Der findes ikke nogen type som hedder xsd:array.
2) Der er indbygget en funktion i NuSOAP: addComplexType, som kaldes nogenlunde sådan:

$server->wsdl->addComplexType( ... )

Det ser ud som om det muligvis er den du skal have fat i?
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 22:04 #33
hmm.. Kan ikke lige se mig ud af hvordan jeg skal stille det op :S
Avatar billede nielle Nybegynder
22. oktober 2007 - 22:10 #34
Hvad siger manualen omkring brugen af addComplexType() ?
Avatar billede nielle Nybegynder
22. oktober 2007 - 22:14 #35
Umiddelbart må det se nogenlunde sådan her ud:

// add types
$server->wsdl->addComplexType(
    'brugernavn,
    'complexType',
    'array',
    '',
    'SOAP-ENC:Array',
    array(),
    array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]')),
    'xsd:string'
);
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 22:20 #36
Jeg har nu:

$server->wsdl->addComplexType(
    'brugernavnArr',
    'complexType',
    'array',
    '',
    'SOAP-ENC:Array',
    array(),
    array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]')),
    'xsd:string'
);

$server->register('getBrugere',
    array('something'=>'xsd:boolean'),
    array('return'=>'tns:brugernavnArr'),
                'urn:bruger',
                'urn:bruger#getBrugere'
    );


Og så funktionen getBrugere fra før..

Men visual studio vil ikke implementere filen nu :S

Den skriver:

Error    2    Custom tool error: Unable to import WebService/Schema. Unable to import binding 'cmrServerBinding' from namespace 'urn:bruger'. Unable to import operation 'getBrugere'. The datatype 'http://schemas.xmlsoap.org/wsdl/:string' is missing.    C:\Documents and Settings\Ole\Skrivebord\Microting -- CMR\Microting -- CMR\Web References\dk.vivaa.ole\Reference.map    1    1    Microting -- CMR
Avatar billede nielle Nybegynder
22. oktober 2007 - 22:24 #37
Sorry ... det der må jeg nok give op over for :^|
Avatar billede nielle Nybegynder
22. oktober 2007 - 22:28 #38
Deres manual må da have et eksempel på noget så simpelt?
Avatar billede vivaa.dk Nybegynder
22. oktober 2007 - 22:29 #39
har siddet og kikket manualen igennem.. men kan ikke finde et godt eksempel :S

Men anyways.. Du har hjulpet rigeligt :)

Takker...
Avatar billede nielle Nybegynder
22. oktober 2007 - 22:42 #40
Ok, så får du et svar fra mig :^)
Avatar billede vivaa.dk Nybegynder
23. oktober 2007 - 10:08 #41
Undskyld jeg spørger igen :)

Den funktion med authenticate..
Hvordan virker den?

Skal jeg lave et test på om _authenticate returnerer 1, der hvor jeg laver mine soap funktioner?
Avatar billede vivaa.dk Nybegynder
23. oktober 2007 - 10:13 #42
Har smidt den ind i toppen af mit dokument og byttet

$server = new soap_server();

Ud med

$server = new MySoapServer();

Men den skriver:

Fatal error: Class 'MyXMLParser' not found in C:\wamp\www\test\index.php on line 12
Avatar billede vivaa.dk Nybegynder
23. oktober 2007 - 10:23 #43
Nå den skal vi ikke tage her.. :) jeg smider et nyt spørgsmål hvis jeg ikke finder en løsning
Avatar billede nielle Nybegynder
23. oktober 2007 - 18:06 #44
Den skal vist ikke nødvendigvis returnere noget bestemt ... det vigtigste er blot at den skal smide en fault (kase en exception) hvis authorizationen fejler.

Som jeg læser koden er det antydet at han - i hans - løsning blot returnere brugeres id som det er sat i databasen.
Avatar billede nielle Nybegynder
29. oktober 2007 - 18:45 #45
vivaa.dk, har du fået løst denne her?

md_craig, lægger du ikke et svar?
Avatar billede vivaa.dk Nybegynder
30. oktober 2007 - 08:37 #46
Nej.. Kan ikke rigtigt finde ud af at få det til at køre..

det lader til at man skal bruge en speciel XMLParser..
Avatar billede md_craig Nybegynder
30. oktober 2007 - 08:40 #47
nielle > narh det er nu dig der har taget det største læs her, jeg har kun besvaret det nemme så overlader point til dig.
Avatar billede nielle Nybegynder
30. oktober 2007 - 18:08 #48
Det fremgår ikke rigtigt hvilken XML parser han bruger, men det er formentligt også ligegyldigt; hvis man kan finde en så kan man bruge den.

I PHP 5 er der faktisk kommet en ganske udemærket XML undersøttelse, så det er nærliggende at bruge den hvis det ellers er muligt.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB

Forsvaret

Cyberspecialist

Forsvarsministeriets Materiel- og Indkøbsstyrelse

IT-Sikkerhedsrådgiver til Cyberdivisionen i Hvidovre

SOS International

Platform Engineer

SOS International

Principal Solution Architect

Forsvarsministeriets Materiel- og Indkøbsstyrelse

Nye kolleger søges til IT Stab i Forsvaret