Основно о преносу података између програма PHP и PY кроз примере. Текстови су писани приоритетно за личну, па тек онда за слободну ширу употребу.

PHP → PY

Пример 1. Пресловљавање ћириличног текста у латинични (питон).

azbuka_srb = ['А','Б','В','Г','Д','Ђ','Е','Ж','З','И','Ј','К',Л','Љ','М','Н','Њ',
'О','П','Р','С','Т','Ћ','У','Ф','Х','Ц','Ч','Џ','Ш','а','б','в','г','д','ђ','е','ж','з','и',
'ј','к','л','љ','м','н','њ','о','п','р','с','т','ћ','у','ф','х','ц','ч','џ','ш']

azbuka_cro = ['A','B','V','G','D','Đ','E','Ž','Z','I','J','K','L','Lj','M','N','Nj',
'O','P','R','S','T','Ć','U','F','H','C','Č','Dž','Š','a','b','v','g','d','đ','e','ž','z','i',
'j','k','l','lj','m','n','nj','o','p','r','s','t','ć','u','f','h','c','č','dž','š']

txt = 'Његош, Ђорђе и Љиља журили су на ћевапчиће.'
for i,x in enumerate(azbuka_srb):

txt = txt.replace(azbuka_srb[i],azbuka_cro[i])
continue

print(txt)
return

Излазни текст је: „Njegoš, Đorđe i Ljilja žurili su na ćevapčiće.“ ߛ

Уместо унапред датог txt ставите

txt = input('Унеси ћирилични текст:')

да би корисник могао унети свој текст. Ставите def cirlat(): испред свега, лево бар једном празнином, да дефинишете дате наредбе као питонову функцију cirlat(). Њеним позивом, она ће функцијом input() тражити унос ћириличног теста txt, пресловити га у латинични и резултат штампати наредбом print.

У програмском језику php питонову варијаблу txt пишемо $txt, дакле са знаком долара испред њеног назива.

Пример 2. Пренос податка из php у python.

Из php програма (небитног назива) наредбама

<?php
$txt = "Ovo je tekst.";
echo shell_exec("python test.py \"$txt\"");
?>

позивамо python програм test.py који гласи

import sys
x=sys.argv
print(x)

Излазни текст је: „['test.py', 'Ovo je tekst.']“ ߛ

Питонов модул sys пружа функције и променљиве које се користе за манипулисање различитим деловима питоновог окружења током извршавања наредби.

sys.argv враћа листу аргумената наредбе прослеђене скрипти, где је sys.argv[0] назив скрипте, а sys.argv[1] послата варијабла.

Пример 3. Укуцавање текста и пренос садржаја у python.

У овом PHP, првом програму, укуцате текст.

Текст:

Унешени текст се проследи на читање и могућу обраду другом програму (naziv2.php). Други га прослеђује трећем (naziv3.py), на евентуалну дораду и штампање. ߛ

Кодови су овде крајње једноставни да би се лакше дограђивали. Први програм преузима текст "name" од корисника и шаље га уобичајеном HTML формом:

<form action="naziv2.php" method="post">
<input type="text" name="name" ><input type="submit">

Други програм, на уобичајени PHP начин, преузима текст из прве форме и шаље га трећем:

$txt = $_POST["name"];
echo shell_exec("naziv3.py \"$txt\"");

Коначно, трећи програм на питонов начин преузима текст и штампа га:

import sys
x=sys.argv
print(x)
sys.exit

На унешени текст Ovo je poruka. коначни одговор је

['piton38_32.py', 'Ovo je poruka.']

што је типична питонова двочлана листа која нам сада каже да је тачан назив трећег, коначног програма piton38_32.py, а послата порука била је Ovo je poruka.

Међутим, ако послати текст садржи нека „чудна“ слова, која су ипак дефинисана UTF-8 кодом, на крају ће се појавити њихов одговарајући хексадецимални запис.

На пример, у првом програму унешена реч „Чађ“ из трећег излази кодирана као '\xd0\xa7\xd0\xb0\xd1\x92'. У питону унесите

b'\xd0\xa7\xd0\xb0\xd1\x92'.decode('utf-8')

добићете 'Чађ'. У питону унесите

u'Чађ'.encode('utf-8')

добићете назад b'\xd0\xa7\xd0\xb0\xd1\x92'.

Други пример, у првом програму унешена реч „Đorđe“ из трећег излази кодирана као '\xc4\x90or\xc4\x91e'. У питону унесите

u'Đorđe'.encode('utf-8')

добићете назад b'\xc4\x90or\xc4\x91e'.

Дакле, у примеру 3, послати текст Đorđe питон штампа делимично кодирано '\xc4\x90or\xc4\x91e', јер слово које није у ASCII коду он уникодира. Тим мешањем добијамо додатно компликовање обраде.

Пример 4. Обрада кода у питону.

Делимични уникод текста Đorđe је '\xc4\x90or\xc4\x91e', па дефинишемо варијабле питоновим наредбама редом:

v1 = '\xc4\x90or\xc4\x91e'
v2 = list(v1)
v3 = []
for i,x in enumerate(v2): v3.append(ord(v2[i]))

Добили смо листу v3 = [196, 144, 111, 114, 196, 145, 101] чији су елементи декадних кодови слова текста Đorđe. Даље настављамо у питону:

v4 = bytes(v3)
v5 = v4.decode('utf-8')

Добијено v5 је Đorđe. ߛ

Иначе, низ ових наредби је моја приватна функција utftxt(x). Она рецимо аргумент x = '\xc4\x90or\xc4\x91e' пресликава у Đorđe. Због начина читања варијабли, као текста или броја и интерпретације броја у базама, питон прави проблеме са овом конверзијом и настаје потреба за овом функцијом. Питон неке наредбе различито извршава непосредно и из функције.

Пример 5. Пренос непромењеног текста.

Текст:

У овом PHP програму yкуцани текст прослеђује се другом PHP програму који га чита и текст преноси трећем PY програму на евентуалну обраду и штампање. ߛ

На овај пример се може надовезати неки уредник „чудних“ азбука. Ради комплетности са горњим „ћирилизатором“ (пример 1), који преводи ћирилицу у латиницу, наводим и симетричан питонов програм за обрнуто превођење, са латинице на ћирилицу. Он је latcir().

Пример 6. Пресловљавање латиничног текста у ћирилични (питон).

slova_srb=['Љ','Њ','Џ','љ','њ','џ','А','Б','В','Г','Д','Ђ','Е','Ж','З', 'И','Ј',
'К','Л','М','Н','О','П','Р','С','Т','Ћ','У','Ф','Х','Ц','Ч','Ш','а','б','в','г','д',
'ђ','е','ж','з','и','ј','к','л','м','н','о','п','р','с','т','ћ','у','ф','х','ц','ч','ш']

slova_cro=['Lj','Nj','Dž','lj','nj','dž','A','B','V','B','D','Đ', 'E','Ž','Z', 'I','J',
'K','L','M','N','O','P','R','S','T','Ć','U','F','H','C','Č','Š','a','b','v','g','d',
'đ','e','ž','z','i','j','k','l','m','n','o','p','r','s','t','ć','u','f','h','c','č','š']

txt = 'Njegoš, Đorđe i Ljilja žurili su na ćevapčiće.'
for i,x in enumerate(slova_cro):

txt = srb.replace(slova_cro[i],slova_srb[i])
continue

print(txt)
return

Излазни текст је: „Његош, Ђорђе и Љиља журили су на ћевапчиће.“ ߛ

Обратите пажњу на другачији редослед слова у овом примеру (6) од онога у претходном (1). Овај низ слова може се користити у горњем примеру, али горњи у доњем не.

Примере 1 и 6 навео сам просто као демонстрацију једноставности и у том смислу моћи Python-а у односу на JavaScript, чији код за исти посао (ћирилизатор) је и на овом сајту, а који је десетинама пута дужи.

Напомињем да скоро ништа, или много тога из ових примера није било могуће наћи на интернету или по форумима компјутераша у време до почетка јуна 2021. када сам правио ову страницу.

PHP ⇄ PHP

Приметимо да је овај PHP програм (пример 3 и пример 5) прослеђивао податке другим PHP програмима да би их они даље слали у PY на извршавање. Сви су ти програми инсталирани на истом интернет серверу. Том иначе једносмерном формом PHP програми могу комуницирати (размењивати податке) сами са собом као и међусобно.

Пример 7. PHP шаље текст самом себи.

Текст:

У овом PHP програму yкуцани текст прослеђује се самом себи и штампа непосредно испод уноса, а било је могуће послати га било где на овој страници. ߛ

Од многобројних података са сервера, попут:

IP адреса сервера: 92.205.0.137
Назив сервера: www.rvukovic.net
Назив програма: /Piton38.php
Метод приступа: GET
IP адреса корисника: 18.191.46.36

користио сам само назив програма. Програм самом себи шаље податке горњом методом, путем сервера, због чега мора знати своје име, своју „адресу становања“. То је довољно да „пошта“ стигне где треба.

Пример 8. Текст се шаље другом PHP програму на евентуалну обраду, а отуда очекује слање резултата и потврда.

Текст:

Унешени текст ће се појавити у другом PHP програму (евентуално обрадити) и вратити са потврдом о активности. ߛ

Пример 9. Други PHP програм ће удвостручити послати број без чекања. Користите децималну тачку уместо зареза!

Број:

Резултат се штампа непосредно испод уноса, ако је било активности. ߛ

Тежи део овог процеса многима је интригантно враћање резултата из другог програма без чекања, па наводим наредбе само тог дела:

< form action="Piton38.php" id="polje" method="post" >
< input type="text" name="povrat9" value="<?php echo $broj; ?>";>
<form>

<script< window.onload = function() {
document.getElementById("polje").submit();
}
</script>

Први део дефинише (необичну) HTML форму за пренос податка ($broj) у први програм, а подршка му је JS, скрипта која првом делу наређује да пренос крене без чекања на потврду и евентуални додатни текст корисника.

Сада кликните кажипрстом по мишу негде на слободну површину програма, па кликните средњим и бирајте да погледате „извор странице“. У Google претраживачу то ће писати View page source, у Firefox-овом View Page Source, или само Page source ако користите рецимо Opera Browser. Шта год, отвориће се нова страница са кодом овог програма и на њој, колико та страница дозвољава, могу се видети детаљи програмирања ових примера. Затим идемо даље.

JSON метод

У примерима 2, 3, 4 и 5 бавили смо се преносима варијабли из PHP програма у PY. Ти су преноси аутоматски покретали наредбе циљаног питоновог (PY) програма. Међутим, позивом на интернету просто као што се то ради са PHP или HTML програмима, навођењем адресе (која се код python-а завршава са name.py), не би започео процес извршавања наредби питона већ би се десио њихов неми приказ, излиставање.

Пример 10. Покретање наредби PY из PHP.

$izlaz = shell_exec('python ime_programa.py');

„Штампана“ са print $izlaz; или echo $izlaz; варијабла $izlaz покреће питонов програм назива ime_programa.py. ߛ

Име варијабле ($izlaz) овог примера може бити било које дозвољено синтаксом програма PHP. Оно је пасивно (до позива за „штампање“) и може стајати било где у том програму. Назив ime_programa.py састоји се из два дела, првог испред и другог иза тачке. Први је произовљан али у оквирима синтаксе интернета, док је други обавезна екстензија py питонових програма.

Када два програма (PHP и PY) нису на истом нивоу адреса (фолдера, директоријума), параметре (python и ime_programa.py) варијабле ($izlaz) пишемо детаљније нпр. /usr/name/python), на начин који зависи од платформе интернета на којој се они налазе.

У HTML програму, уосталом као и у PHP, испред и иза варијабле примера 10 требају стајати ознаке редом <?php и ?>. Такође, сагласно примеру 2, варијабли $izlaz могуће је додати и трећи параметар, рецимо \"$txt\", где је $txt варијабла којом се из PHP преноси нека вредност у програм ime.py, а који се затим извршава.

JSON (JavaScript Object Notation) је пакет програма за смештање и размену података који такође постоји као питонов модул. Као и други модули, он се у питону активира наредбом import json, а првенствено се користи за пренос података између сервера и веб апликација.

Пример 11. Учитавање JSON објекта у PY.

import json
x = '{ "ime":"Jovan", "dob":25, "grad":"Banja Luka"}'
y = json.loads(x)
print(y['dob'])

Извршавањем овог програма, штампа се: 25. ߛ

То је једноставна употреба json-а у питону за приказ вредности (25) кључа (dob) из датог речника (x). Овај речник је писан синтаксом JSON-а и није непосредно читљив питону (PY), као нити другим програмским језицима. Наводни речник (x) заправо не мора бити ни директно разумљив нити видљив на овај начин. Када сваки од страних језика има сопственог преводиоца за JSON, размена података његовом услугом постаје универзална.

Наредбе json.loads() и json.dumps() врше међусобно обрнуте конверзије. Прва објекат JSON-а преводи у објекат питона, а друга инверзно, објекат питона преводу у објекат JSON-а. То је управо оно што нам треба за комуникацију између програмских језика, који се иначе сами не разумеју, па стога наводим и следећи пример.

Пример 12. Депоновање PY објекта у JSON.

  import json  
  x =  { 
    "ime": "Jovan", 
    "dob": 25, 
    "grad": "Banja Luka" 
  } 
  y = json.dumps(x) 
  print(y['dob']) 

Извршавњем овог програма биће штампано:

{"ime": "Jovan", "dob": 25, "grad": "Banja Luka"}

а то (y) је речник (x) на начин JSON-а. ߛ

Одшампано видимо како видимо, јер и екран има свог JSON преводиоца. Поред речника (dictionary), питонову скрипту json користимо за код објекта (object), записа (record), хеш табеле (hash table), листе кључева (keyed list) и за асоцијативни низ (associative array).

Поновићу, у провом примеру (11) наредбом y = json.loads(x) варијабли y придружен је речник x, писан питону неразумљивим кодом, из којег је наредбом print(y["dob"]) издвојена дата одредница њему читљива и њена вредност је штампана. У другом примеру (12) питонов начин писања речника (x) преведен је (y) за JSON и тиме омогућено слање и читању тог речника неком питону непознатом језику.

Пример 13. Шифровање PHP објекта за JSON.

<?php  
  $myObj->ime = "Jovan";  
  $myObj->dob = 25; 
  $myObj->grad = "Banja Luka"; 
  $myJSON = json_encode($myObj); 
  echo $myJSON; 
?>

Извршавање овог PHP програма резултира исписом:

{"ime":"Jovan","dob":25,"grad":"Banja Luka"}

а то је објекат JSON-а (на језику екрана). ߛ

Видљиво је колико се наизглед разликују почеци примера 12 и 13. Они говоре о истом, али први на PY а други на PHP начин. Први, PY податке пакује у „речник“ (dict), други у PHP-у пакује их у „низ“ (array), а припремају их да у JSON-у буду „објекат“ (Object). Депоновања података из PY у JSON врши функција json.dumps(), а одговарајућа у PHP-у назива се шировањем и врши је функција json_encode().

Пример 14. Шифровање PHP низа (array) за JSON.

<?php  
  $myArr = array("Jovan", "25", "Banja Luka");  
  $myJSON = json_encode($myArr); 
  echo $myJSON; 
?>

Извршавање овог PHP програма резултира исписом:

["Jovan","25","Banja Luka"]

а то је и у JSON-у неки „низ“ (Array). ߛ

Обрнута функција PHP фунцкији json_encode() је функција json_decode(). Њена употреба је из последња два примера прилично јасна, али морамо имати у виду и разлике између њих две. Функција дешифровања (decode) може имати четири параметра. Први варијабла је „низ“ (string), друга je логичка вередност (true: излаз је асоцијативни низ; false: излаз је објекат), трећа ограничава дубину декодирања, а четврта налаже управљање грешкама.

Пример 15. Пренос из PHP у PY и назад.

<?php 
  $data = array('Jovan', '25', 'Banja Luka');
  $transfer = shell_exec('python ime.py ' 
            . escapeshellarg(json_encode($data)));
  $transData = json_decode($transfer, true);
  var_dump($transData); 
?>

Овај PHP програм обраћа се PY програму:

  import sys, json 
  data = json.loads(sys.argv[1]) 
  transfer = {'status': 'Ok!'} 
  print json.dumps(transfer)

array(1) { ["status"]=> string(3) "Ok!" }

Последњи ред штампа крај PHP програма. ߛ

Из PHP подаци $data отишли су у PY програм формирајући:

data = [u'Jovan', u'25', u'Banja Luka']
$transfer = {"status": "Ok!"}
$transData = Array.

Функција escapeshellarg($txt) смешта аргумент ($txt) у наводнике и обезбеђује да та варијабла не буде рецимо извршна наредба. Даље, у повратку из PY овај PHP програм штампа „члана низа“, array(1), чији кључ је 'status' а вредност је 'Ok!', иначе реч дужине три слова, string(3). Тај низ је додат у PY ради провере повратка података у PHP програм.

Приметимо да је пренос података помоћу JSON-а, за разлику од претходних (пример 10), двостран, наизглед компликованији, али да он такође покреће наредбе циљаних доставом, осим што је у овом примеру (15) тај други (PY) процес „незаустављив“.

File метод

Претходни примери наводе нас да комуникацију страних програма помоћу посредника даље генерализујемо. Уводећи као посредника „обичну“ датотеку актери не морају бити у журби са одговорима. Могу се понашати као саговорници на интернет форуму, бирајући да ли да сви говоре исти језик, или да сваки од њих има сопственог преводиоца за „језик форума“. Тај језик форума, копјутерски „есперанто“, идеја је коју можемо посудити од JSON методе.

У случају велике гужве на интернет платформи, на којој би страни програми комуницирали, добро је да тих „датотека посредника“ буде више и да њихова имена буду лозинке познате само одређеним групама, али принцип рада је исти са познатом, шифрованом или фантомском (која се гаси након употребе) датотеком. Прва од таквих је у следећем примеру.

Пример 16. PHP → позната тека → PY и назад.

Текст:

Посредна датотека: „Текст PHP // Текст PY “. ߛ

Унешени текст шаље се самом себи (пример 7) и уједно уписује у дату несакривену „теку посредовања“. Затим иде нема порука питоновом програму да се покрене (пример 10). Тај отвара и чита исту теку да би евентуално обрадио шта треба и додаје јој нови запис. Нема непосредног слања текста нити из PHP у PY нити обрнуто!

Ову наводно познату теку (корисник је са мало труда може открити, а затим и читати са треће локације) у следећем примеру шифрујемо користећи IP (Internet Protocol) „адресу“ сервера. Ову адресу сваки од програма, PHP и PY, сазнаје на свој начин, кодира заједничким поступком формирајући име посредне датотеке и тако је налази.

Пример 17. PHP → скривена тека → PY и назад.

Текст:

Образац за излаз је исти као у претходном примеру. ߛ

Овде такође нема потребе да два програма непосредно размењују било какве податке. У датом тренутку IP адреса сервера је иста за оба програма (за сада PHP и PY), а програмер може смислити превише начина да помоћу ње креира назив посредне датотеке и додатно отежа њену злоупотребу. Ево програма који су овде употребљени, PHP па PY.

<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
Текст: <input type="text" name="unos17">
<input type="submit" value="Потврди" ></form>

<?php if ($_SERVER["REQUEST_METHOD"] == "POST") {
$unos17 = $_POST['unos17'];
if (empty($unos17)) {
echo "<br> Нема активности!";
} else {

$teka17 = str_replace('.','',$_SERVER['SERVER_ADDR']) . '.txt';
$file17 = fopen($teka17, "w") or die("Unable to open file!");
fwrite($file17, "PHP: " . $unos17. " // ");
fclose($file17);
echo shell_exec("python Piton38_171.py");
$file17 = fopen($teka17, "r") or die("Unable to open file!");
echo '
' . fgets($file17);
fclose($file17);
//unlink($file17);
}

}
?>

Дакле, PHP у шифровању имена посредне датотеке користи низ бројева и тачака адресе сервера из којег за сада само уклања тачке. Исто ради PY програм и једини променљиви текст којим они комуницирају је садржај те датотеке.

   import socket
   x = socket.gethostbyname(socket.gethostname())
   y = x.replace('.','') 
   teka = y + ".txt"
   f = open(teka, "a")
   import datetime
   u = datetime.datetime.now()
   v = u.strftime("%Z %d %b %Y %H:%M")
   txt = "PY: Резултат! (CST " + v + ")"
   f.write(txt)
   f.close()

Датум и време записа у питоновом програму додао сам ради контроле и потврде да програми заиста комуницирају путем ове датотеке. То време је CST (Central Standard Time), које као и адреса сервера не мора бити једнако локалном.

Следећи корак у заштити комуникације између програма могла би бити употреба локалне IP адресе. Она је иста за појединог корисника и може се употребити иста метода овог примера (17). За исти шаблон кодирања, различите локалне адресе даваће различите посредне датотеке чије име корисницима неће бити познато.

Међутим, много корисника имаће много различитих локалних адреса и креираће много посредних датотека. Зато у таквом случају треба обезбедити и помоћни програм који ће чистити сервер од таквих датотека након њихове употребе. То нарочито у случају још сигурније заштите, ако сваки пут програми креирају нову посредну датотеку. Ако је PHP генерише на случајан начин, онда питону мора слати и кључ као трећи параметар „неме наредбе“ (пример 10).

Слична овима је комуникација путем база података (SQL), али та метода већ излази из оквира прича о „брзом софтверу“ (quick software).

About Python

Versions of “Python 3.8”, the interpreter programing kind of language, appeared from October 14, 2020 to May 3, 2021. It is an object-oriented, high-level programming language with dynamic semantics.

Guido and Rasmus

The founders of Python and PHP are considered to be Guido van Rossum (1989) and Rasmus Lerdorf (1995), pictured from left to right.

Python is a programming language that lets you work more quickly and integrate your systems more effectively. – it says on their site: python ⋙

The other languages

PHP (Personal Home Page) is a popular general-purpose scripting language that is especially suited to web development. – says PHP ⋙

HTML (Hypertext Markup Language) is a standardized system for tagging text files to achieve font, colour, graphic, and hyperlink effects on World Wide Web pages. Free course at HTML Tutorial ⋙

CSS (Cascading Style Sheets) is a style sheet language used for describing the presentation of a document written in a markup language such as HTML. Free templates at CSS ⋙

Decoding

In Example 3 (Пример 3), after the transfer you can get something like
'\xd0\xa7\xd0\xb0\xd1\x92', which is the hexadecimal code of the Cyrillic text Чађ (Soot). If ASCII cannot be displayed, hex is displayed. The UTF-8 (Unicode Transformation Format) characters you can see on UTF-8 ⋙

Python's b'\xd0\xa7'.decode('utf-8') gives the Cyrillic letter 'Ч'. Conversely, the python's u'Ч'.encode('utf-8') returns starting b'\xd0\xa7'.