[Delphi, PHP] jak získat result php funkce

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod dyžon 16. 5. 2019 08:02

zdravím,
mám dotaz, jestli jde nějak získat result z php funkce (scriptu).
dejme tomu, že mám na svém FTP soubor akce.php s funkcí vratData();
result této funkce je lehce upravený řádek z databáze mySql.

existuje nějaký způsob, jak z Delphi XE zavolat tuhle funkci a dostat result ?

napadá mě třeba převést to na string a ten pomocí header(Location: akce.php?.$result;
a pomocí Webbrowser1.LocationURL a odečtení URL dostat string, kterej potom zase převést na TItem.
tady je problém, že adresní řádek má omezenej počet znaků.
nebo to vypsat jako string pomocí echo na stránku a zase pomocí TWebBrowseru přečíst html stránky (zkoušel jsem i TIdHttp, ale tam to nemůžu zprovoznit). No vlastně s Webbrowserem mám taky problém, sice nějakej text zobrazím, ale je problém v kodování (samé čínské znaky a podobně).
obě dvě varianty jsou ale strašný ... a to nemluvím o rychlosti.

existuje tedy nějaký lepší řešení ?
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 16. 5. 2019 18:23

Jedním slovem - PHP soubory nelze volat jinak než přes webový server, kde je soubor umístěn ( tj. obvykle port 80 )
Další - nešlo by tu otázku lépe zformulovat, aby byla k pochopení? Nechápu, která část se týká PHP a která Delphi.
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod dyžon 17. 5. 2019 08:26

jasně, příklad:
na FTP mám soubor ... akce.php:
Kód: Vybrat vše
<?php
   function vypisVsechnyVcetneID() {

      require_once('config.php');

      $pripojeni = mysqli_connect(DBHOST, DBUSER, DBPASS) or die(mysqli_error());
      mysqli_select_db($pripojeni, DBNAME) or die(mysqli_error($pripojeni));

         $dotaz = "SELECT * FROM chefs";
         $vysledek = $pripojeni-> query($dotaz);
         $pocet_radku = mysqli_num_rows($vysledek);

            if($vysledek-> num_rows > 0)
            {
               while ($radek = $vysledek-> fetch_assoc())
               {
                  $zprava .= $radek["name"]."|".$radek["id"]."|";             
               }
            return $zprava;
            }
   }
?>
je to jen příklad.
no a z Delphi bych potřeboval něco jako:
Kód: Vybrat vše
...
var Net: TIdHttp; NetText: String;
begin
  Net:= TIdHttp.Create(self);
  NetText:= Net.GetReturnOfFunction('http://.../akce.php', vypisVsechnyVcetneID());
v akce.php už to převádím na string, ale klidně může vracet typ TItem
na string to převádím proto, že můj nápad je to vypsat buď do stránky
Kód: Vybrat vše
<?php
--- stejny ...
?>
<!DOCTYPE html>
<html>
    <head>
        <title>php_funkce</title>
    </head>
    <body>
      <?php echo vypisVsechnyVcetneID(); ?>
a pak pomocí funkce GetHtml, kterou ještě nemám úplně v pořádku, proto ji tady neuvádím to načtu do netText: STtring;
nebo to můžu strčit do adresního řádku:
Kód: Vybrat vše
<?php
   require_once('config.php');
   
   function vypisVsechnyVcetneID() {
      $pripojeni = mysqli_connect(DBHOST, DBUSER, DBPASS) or die(mysqli_error());
      mysqli_select_db($pripojeni, DBNAME) or die(mysqli_error($pripojeni));

         $dotaz = "SELECT * FROM chefs";
         $vysledek = $pripojeni-> query($dotaz);
         $pocet_radku = mysqli_num_rows($vysledek);

            if($vysledek-> num_rows > 0)
            {
               while ($radek = $vysledek-> fetch_assoc())
               {
                  $zprava .= 'jmeno='.$radek["name"]."&id=".$radek["id"]."&";             
               }
            header ('Location: akce.php'.'?'.$zprava;
            }
   }
vypisVsechnyVcetneID()
?>
a z Delphi:
Kód: Vybrat vše
const url_akce = 'https://.../akce.php';
...
begin
  WebBrowser1.Navigate(url_akce);
end;

procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject; const pDisp: IDispatch; const URL: OleVariant);
var netText: String;
begin
  netText:= WebBrowser1.LocationURL;
  netText:= copy(netText, length(url_akce) + 1, length(netText);
end;
ale jak už píšu nahoře, obě moje řešení mi připadají špatný, tak se ptám, jestli to nejde udělat právě pomocí něčeho jako je TIdHttp.GetReturnOfFunction(file.php, functionName);
vím že GetReturnOfFunction neexistuje, ale snad už je to srozumitelnější.
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 18. 5. 2019 11:25

První doporučení - pro SQL query bych dodal ORDER BY a ASC ( nebo DESC )
Dále bych se podíval jak se používá mysqli v PHP - je tam přímo ukázka kódu.
Nevěřím, že je tato PHP část bez chyb.

Pro Delphi - volil bych nějakou free komponentu na práci s JSON, protože práce s JSON je v PHP rychlejší než vypisování a parsování z Array na String.
Jinak nějakou komponentu na práci s CSV.

Poslední část kódu pro Delphi je hodně špatně - zacyklení. Volil bych jen obyčejné stažení souboru - tedy odpadá parsování html kódu.

A teď k zprovoznění.

U PHP postačí mít kód jak je u prvního bloku - jen změnit "return" za "echo" a dopsat volání fce "vypisVsechnyVcetneID()" aby se při načtení stránky "akce.php" rovnou fce vypsala ( ideální by bylo to nepsat jako funkci, pokud se k ní neodkazuješ i jinde )

U Delphi je potřeba Indy komponenty správně nastavit a mít všechny - případně i řešit SSL vrstvu.
A primárně bych se zaměřil na nalezení tutoriálu jak s pomocí Indy stáhnout soubor - resp. uložit načtený soubor.
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod dyžon 20. 5. 2019 08:20

děkuji za vyčerpávající odpověď,

celou tu část php jsem psal v práci z hlavy, takže tam jsou chyby, šlo mi jen o to, aby bylo vidět, že funkce ve scriptu sahá do databáze na serveru, takže toho si moc nevšímej ...

na JSON jsem se díval a vypadá to dobře, nastuduju.

omlouvám se, ale nezmínil jsem, že project je multidevice (delphi FMX),
které nepodporují komponenty Indy.

jde mi vlastně hlavně o to, připojit se z jakéhokoliv zařízení do MySQL databáze na svým serveru.

jediny řešení, ktery mi funguje je se připojit pomocí php, který visí na stejným serveru.
pokud se do databáze zkouším připojit pomocí komponent, tak neúspěšně.
musel bych na serveru povolit každé IP, na kterym poběží aplikace a to je nesmysl.

takže vlastně potřebuju z toho php, popřípadě javascriptu dostat do delphi FMX návratnou hodnotu různých funkcí.

ideálně bez použití TWebBrowseru.
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Nargon 21. 5. 2019 15:51

Po přečtení toho co vlastně chceš bych ti asi doporučil zcela jiný přístup. Přes PHP a JSON to asi půjde ale nemyslím si že to chceš dělat, protože pak narazíš na spoustu srágor při parsování odpovědi. Mám tím na mysli rozdíl ve formátu. Na jedné straně zapíšeš desetinné číslo, ale někteří klienti ti budou padat, protože očekávají desetinou tečku, nikoliv desetinou čárku.
Cesta přes PHP je dobrá tak když chceš získat nějakou jednoduchou hodnotu, jako třeba počet uživatelů v databázi. Ale pro přenos složitějších datových struktur jako jsou například celé tabulky (SELECT * FROM XXX) je to asi cesta do pekel.

Osobně bych volil cestu přes WebService. Tam budeš mít jednu serverovou část, která bude mít přístup do DB. Pak klidně několik klientů, kteří se budou připojovat na webservice a budou s ní komunikovat. Určitě najdeš i spoustu návodů jak na to. Například jeden z prvních co jsem našel: http://etutorials.org/Programming/maste ... +Services/
No zkus googlit: delphi webservice wsdl.

Ale na druhou stranu, nevím zda webservice není pro tebe zbytečně složitá věc, vzhledem ke tvým dotazům to možná bude nad tvoje síly. A já ti s tím moc neporadím, delphi neznám.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod Just_jo 21. 5. 2019 18:41

Souhlasím s Nargonem, bohužel to bude chtít asi jiný hosting. Předpokládám, že tam, kde teď je nebude mít k dispozici .NET nebo jiné.

Nevidím problém u PHP a JSON - desetinná tečka nebo čárka lze na zařízení přepsat podle zařízení a na serveru postačí pak formátování čísel, které lze u PHP také jednoduše zařídit.

Ohledně Delphi FMX - tady zkušenosti nemám - obecně jsem našel jen příklady s použitím WebBrowser - asi nejjednodušší na zprovoznění, nebo by zbývalo použití nějakých externích komponent.
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod dyžon 22. 5. 2019 09:28

díky,
už jsem se dneska chtěl zeptat, jak byste to řešili vy.
hosting mám na active24, mrknu, jestli tam WebService půjde.
jsem sice lama, ale pokud budu mít nějakej funkční postup, jak něco udělat, tak to většinou zvládnu :o))
včera jsem nakonec vymyslel, že to udělám asi cely v php a v Delphi dám jen TTabControl s 14ti TabStránkama a TWebBrowser, kde poběží ono php a vždycky, když přejdu na další stránku, změním parent TWebbrowseru na aktuální TabStránku a načtu znovu php.

o co vlastně jde:
dělám takovou jednoduchou apku pro dětskou skupinu, respective pro rodiče těch dětí.
budou v ní moci dítě přihlásit na určitý den do kroužku.
takže můj plán je:
Delphi: TPageControl s 14ti stránkama (registrace na 14 dní do předu), první strana:= dnes, druhá strana:= zítra a tak dále... , TWebBrowser, kam načtu php. Parent TWebBrowseru budu měnit na aktuální stranu TPageControlu.

v databázi bude: jméno: string; telefon: string, kluk/holka: boolean; stav(přihlášen/nepřihlášen): boolean; víc toho asi není potřeba.

php: podle datumu sáhne do databáse, vybere aktuální hodnoty, ktery vypíše do html.
přihlášení na ten den se budou vypisovat jako první, (checkbox, ikona, jméno), všechny položky jako enable: False;
pokud se položka bude shodovat s telefonním číslem, bude vypsána jako enable: True;
tím zajistím, že rodiče budou moci upravovat jen svoje dítě.
když rodič zaškrne checkbox, přihlásí dítě na ten den. (změna se hned uloží do databaze.)
počet dětí na den je omezenej, takže když už bude přihlášených (nevím asi 25 dětí), tak se bude vše od 25 pozice vypisovat jako enable: False;

další věc, kterou je potřeba vyřešit je, při spuštění aplikace se zkontroluje, jestli v databazi je zapsanej novej (14tej den). pokud ne, vloží se do db novej záznam, kde budou mít stav všichni False;, a pokud nebou potřebovat žádný statistiky, tak se smaže včerejšek.

nevím, jestli jsem to napsal srozumitelně, každopádně zatím vím, jak a co chci udělat, tak se na to vrhnu.
co zatím nevím je, zápis téhle struktury do databáze, ale google snad něco poradí.
Graphic1.JPG
Graphic1.JPG (32.09 ) Zobrazeno 1758 krát


nebo máte jinej, lepší nápad, jak to udělat ?
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod JirkaVejrazka 22. 5. 2019 09:44

A nebylo by jednodussi tohle udelat ciste jako webovou aplikaci, nez do toho michat jeste Delphi?
JirkaVejrazka
Mírně pokročilý

Odeslat příspěvekod dyžon 22. 5. 2019 10:16

no oni to chcou jako mobilni aplikaci ...
jinak samozřejmě ano ...
dost lidí už je z těch mobilních aplikací úplně mimo, .. dokonce jsem viděl i aplikaci na to, kdy chodit spát, jak dlouho a tak ... měli by spíš poslouchat svoje tělo a né nějakou apku, ale to je na delší povídání .. :o))
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Nargon 22. 5. 2019 11:48

No už jsem viděl pár "mobilních" aplikací, které jsou defakto webová stránka a v mobilu je aplikace, která obsahuje jen "browser okno" bez navigační lišty a je tam natvrdo zadaná www adresa právě toho webu.
Takže to je způsob jak udělat webovou aplikaci a mít jí i defakto jako mobilní. Sice je to z mého pohledu dost prasárna, ale dělá se to.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod dyžon 22. 5. 2019 12:27

no právě moc nezbývá, ale něco takovýho se chystám udělat i já ...
v delphi vlastně udělám jen to, že budou moct prstíkama přecházet na další/předchozí stránku a načítání url do WB. to je vše ... dělám jen jednoduchou věc, takže tady se asi dá přimhouřit oko, ale taky s tím nejsem spokojenej, proto jsem tohle vlákno založil.

zajímá mě, jak se takovýhle apky, kde je potřeba databáze řeší.
ptal jsem se na 3 serverech (wedos, endora, active24) a ani na jednom nedovolují přístup k MySql z třetí strany, pokud nepovolíš IP, což je asi z hlediska bezpečnosti v pořádku.

jak psal Nargon, vytvořit WebService, ale to taky asi nejde úplně všude.
možná by se hodilo sem uvést server, na kterym to jde.
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod JirkaVejrazka 22. 5. 2019 13:12

V tom pripade bych si ta nezbytna data mezi serverem a klientem posilal jako JSON, coz uz tady nekdo zminoval. Je to celkem standardni reseni.
JirkaVejrazka
Mírně pokročilý

Odeslat příspěvekod Just_jo 22. 5. 2019 19:13

Nevím jak v Delphi tvoříš appku i pro iOS, ale asi bych šel do Xamarinu než Delphi.
Už jen to, že u Androidu se standartně využívá WebView, který se aktualizuje samostatně
Just_jo
Junior
Uživatelský avatar

Odeslat příspěvekod dyžon 23. 5. 2019 13:40

tak Delphi FMX TWebBrowser nepodporuje gesture, i když tu vlastnost má, tak ve finále nereaguje, takže to taky nepůjde. fakt zoufalství ..

mrknu na to VisualStudio, .. sice je to v C++ a já se plácám celou dobu v Pascalu, ale snad to nějak dám.
AMD FX-6300; Gigabyte 970A-DS3P; DDR3 8192MBytes; AMD Radeon HD 6700 Series
dyžon
Junior
Uživatelský avatar

Odeslat příspěvekod Just_jo 25. 5. 2019 17:28

Xamarin je tuším spíš C#, ale návodů je na netu taky dost a Android Java a VS C# není moc odlišný
Just_jo
Junior
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků