Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Onko mahdollista tehdä PHP:lla sivutus arraylle?

Sivun loppuun

walkout_ [19.06.2019 15:47:44]

#

Hei,

Onko mahdollista tehdä PHP:lla MySQL-tyyppinen sivutus PHP-arraylle. Eli siis AJAX-kysely (Ext JS 3.4.0) postaa palvelimelle teidot start 0 ja limit 50 jos sivutus on 50 riviä per sivu ja sitten 51-100 sivulle kaksi. Eli jos on niin millaisella PHP-koodilla/functiolla. Zend Frameworkin olla pagination luokalla tämä ei ole mahdollista koska se tarvitsee palvelimelle sivu numeron, yms. Ja Ext JS 3.4.0 ei tue ollenakkaan tälläistä.

Eli siis MySQL:ssä koodi Zend Frameworkilla on tallainen:

$sql_count = 'SELECT * FROM ' . $table
		.' WHERE user_id = '.$id.' AND '. $table .'.title LIKE \'%'.$query.'%\' '
				.'AND '.$table.'.month = '.$db->quote($month, 'INTEGER').' AND '.$table.'.year = '.$db->quote($year, 'INTEGER').' '
		. ';';
		$sql = 'SELECT * FROM ' . $table
		. ' LEFT JOIN hours ON ' . $table
		. '.id=hours.task_id '
		. 'AND hours.year = '.$year.' '
		. 'AND hours.month = '.$month.' '
		.'WHERE user_id = '.$id.' AND '. $table .'.title LIKE \'%'.$query.'%\' '
				.'AND '.$table.'.month = '.$db->quote($month, 'INTEGER').' AND '.$table.'.year = '.$db->quote($year, 'INTEGER').' '
		//.'AND '.$table.'.isLeaf = true '
		.'ORDER BY id ASC LIMIT '
		. $start . ', '. $end.';';

Grez [19.06.2019 16:09:45]

#

walkout_ kirjoitti:

Onko mahdollista tehdä PHP:lla MySQL-tyyppinen sivutus PHP-arraylle.

On, tietenkin. Siihen on jopa valmis funktio:

$sub = array_slice( $array, $start, $length, true);

walkout_ [19.06.2019 16:13:35]

#

Grez kirjoitti:

walkout_ kirjoitti:

Onko mahdollista tehdä PHP:lla MySQL-tyyppinen sivutus PHP-arraylle.

On, tietenkin.

$sub = array_slice( $array, $start, $end, true);

ok.. kiitos tästä testaan asap.

Grez [19.06.2019 16:17:04]

#

Oops, se kolmas parametri oli "pituus" (ei "loppu", kuten vahingossa ennen korjausta laitoin)

walkout_ [19.06.2019 16:57:54]

#

Joo ja tietenkin on hyvä lukea PHP-dokumentaatiota ja ei ole laitonta kopsata sieltä koodi-esimerkeejä. Mutta kun ei näistä aina niin teidä oikeia valmisfunctiota.

Ext JS 4 ja siitä ylöspäin näiden MySQL-sivus juttujen lisäksi ks. systeemi postaa myös automaattisesti sivunumeron palvelimelle joten Zend Framework -sivutusluokka toimii näillä kuin pommi.

Ext JS 4 mulla on kyllä lisenssi, joka makso paljon joten silläkin voisi tehdä mutta kun projektilla on niin kiire että ei vaan ehdi koodata kaikkea uusiksi Ext JS 4+:salla.

On vähän kummaa että nykyään Ext JS:ssä ei saa ilmaiseksi vaikka se on oletuksena GNU GPL ja jos maksaa tuotteesta niin saa tehdä suljetun lähdekoodin ohjelman. Tämä minun nykyinen projekti on GNU GPL -lisensotitu ja silti en saa ilmaiseksi Ext JS:ssä enää.

Grez [19.06.2019 17:35:30]

#

walkout_ kirjoitti:

On vähän kummaa että nykyään Ext JS:ssä ei saa ilmaiseksi vaikka se on oletuksena GNU GPL

Kuinka niin? https://www.sencha.com/legal/gpl/

Vai tarkoitatko, että vain major versiot julkaistaan GPL:näkin, eli esim. 6.0 mutta ei 6.7.

Ehkä voisit myös harkita jotain sellaista js frameworkia, jonka avointa versiota saa käyttää myös suljetun koodin tuotteissa, niitäkin näyttää olevan toista kymmentä https://en.wikipedia.org/wiki/Comparison_of_JavaScript_frameworks

walkout_ [20.06.2019 09:39:59]

#

Sain nyt toimimaan koodin oikein näin päin:

$paginator = array_slice($json, $start, $end, false);

		$success = array('success' => true,
				'totalCount' => $ii,
				'tasks' => $paginator);

		echo Zend_Json::encode($success);

jos toi viimeisin olisi ollut meinaan true niin listaus olisi väärin päin eikä näin ollen toiminut oikein. Eli sivulla kaksi ei olisi näkynyt mitään.

The Alchemist [21.06.2019 21:37:34]

#

No ei vaan sulla on taulukko php:ssä väärin päin, siinä se vika on.

Taulukon indeksien "säilyttäminen" on tarkoitettu lähinnä sitä varten, että taulukon rivit voi indeksoida käyttäen jotain muuta kuin juoksevaa numerointia. Jos kuitenkin haluat käyttää juoksevaa numerointia mutta rivien järjestys on väärä (eli jostain syystä indeksien järjestys sekaisin), niin silloin oikeastaan vain kierrät omassa koodissasi olevaa bugia tavalla, joka toimii nyt mutta on rikki taas ensi kerralla jossain toisessa yhteydessä.

Php:ssä jopa numeeriset indeksit voivat olla mielivaltaisessa järjestyksessä ja se on "ihan ok". Sen sijaan javascriptissä ja jsonissa Array-tyyppi on aina indeksoitu 0...n kasvavassa järjestyksessä. Eli jos muunnat php-taulukon jsoniksi, niin rivit voivat asettua eri järjestykseen, mikäli php-taulukon indeksointi on jostain syystä epäjärjestyksessä.

Oikeastaan saattaa käydä jopa niin, että php:n json_encode()* sarjallistaa taulukon tällöin Arrayn sijaan Objectiksi, mutta ainakin Firefoxin ja Chromen kanssa lopputulos on jossain mielessä sama, koska niiden implementaatio toimii siten, että Objectin numeeriset jäsenet asettuvat aina kasvavaan järjestykseen oliota iteroidessa. Kyse ei kuitenkaan ole standardista ominaisuudesta, joten siihen ei kannata luottaa.

Alla esimerkki siitä, mitä edellisessä kappaleessa yritin selittää:

// Php-taulukon muuttaminen jsoniksi
print json_encode([0 => 'a', 2 => 'b', 1 => 'c']);

// Tulostaa {"0": "a", "2": "b", "1": "c"}

// Selaimessa järjestys kuitenkin voi muuttua:
console.log({0: 'a', 2: 'b', 1: 'c'})

// Tulostaa todennäköisesti {0: 'a', 1: 'c', 2: 'b'}

* Voi olla, että Zendin enkooderi käyttää omaa implementaatiotaan ja lopputulos on siksi esimerkistäni poiketen esim. (json-)Objectin sijaan Array mutta indeksit ns. loogisessa järjestyksessä.

walkout_ [22.06.2019 10:32:15]

#

Siis ohjelma hakee oletuksena desc-järjestyksessä palvelimelta dataa PHP-taulukkoon jos sitä ei ole eriksen määritetty onko se DESC vai ASC. Kiitos kuitenkin huomautkesta sillä minun JavaScript-kutsussa oli ASC ja PHP-puolella DESC.

Sitten ORDER BY on oletuksena muuten created_date eli rivin luontipäivä.

Eli ei voi toimia oikein jos kerran Ext JS -taulukossa on ORDER BY ID.

Homma on siis tämä:
https://developers.freshdesk.com/api/#list_all_tickets

Siis minun koodi ei ole tehty oikein verraten siihen miten Freshdesk tomii.

walkout_ [23.06.2019 11:12:50]

#

$phpNative = Zend_Json::decode($body);
var_dump($phpNative);

Tulostaa, että se on Array ja on nousevassa järjestyksessä.

Sitten alkaa koodi:

$json = array();
$ii = 0;
foreach ($phpNative as $key => $value) {
	$json[$ii]['id'] = $value['id'];
    $ii++;
}
var_dump($json);

Tulostaa, että se on Array ja indexit ovat nousevassa järjestyksessä mutta eivät sekaisin epäloogisesti.

var_dump(Zend_Json::encode($success));

Tulostaa, että koko hoito on String.

The Alchemist [24.06.2019 05:52:13]

#

Tuossa sun foreach-loopissasi ei kyllä ole mitään järkeä. SQL-kysely* palauttaa jo valmiiksi taulukon juoksevalla numeroinnilla eli sitä ei tarvitse resetoida. On myös aika turhaa yrittää optimoida lukemalla pelkät id:t taulukkoon. Voit siis palauttaa suoraan kyselyn tuloksen sellaisenaan tai korkeintaan suotia pois sellaiset kentät, mitä ei ole tarkoitus näyttää julkisesti ollenkaan.

* Tai mikä ihme "$phpNative" onkaan. Muuttujan nimi on todella huono, se ei oletettavasti kerro mitään muuttujan sisältämän datan luonteesta.

Samoin että mikä ihmeen "$ii"? Vaikka ei olekaan mitään pakkoa käyttää aina indeksilaskurina juuri $i-nimistä muuttujaa, niin on aika outoa, että päätät rikkoa käytäntöä keksimällä uudeksi nimeksi $ii. Olisi parempi käyttää joko yleisiä käytäntöjä tai tietyissä tilanteissa nimetä laskurikin havainnollisesti käyttötarkoituksensa mukaisesti.

walkout_ [24.06.2019 10:15:35]

#

Siis cURL REST Client hakee ensin Ticketit Freshdeskistä ja tekee niistä vain JSON-stringin joten se pitää ensin decodata koodilla:

$phpNative = Zend_Json::decode($body);

Ja sitten ajaa Foreach loopilla Arrayksi, josta encodataan sitten EXt JS 3.4.0 tomiva JSON-palaute.

Koko ohjelmassa ei ole MySQL-käytetty muuta kuin APIKey:n ja Freshdesk URL:n hakemiseen minne REST-kutsu tehdään.

Ja MySQL tietokannassa APIKey on salattu tehokkaammalla salauksella kuin esim. mcrypt. Ja mcrypt ei ees toimi enää uusimmissa Unbuntu Server LTS versioissa koska se funktio on poistettu uusimmista PHP-verioista.

Grez [24.06.2019 10:38:22]

#

walkout_ kirjoitti:

Ja MySQL tietokannassa APIKey on salattu tehokkaammalla salauksella kuin esim. mcrypt.

Jokseenkin huvittavan kuuloinen lausahdus, kun mcrypt ei ole mikään salausalgoritmi, vaan PHP-laajennus, jossa on tuki useille erilaisille salausalgortimeille, kuten vaikkapa AES256.

Toki voi olla että käytät jotain sellaista algoritmia, joka on tehokkaampi kuin mikään mcryptistä löytyvä, mutta silti huvittaa että miksi et vaan sano mitä algoritmia käytät vaan kirjoittele tuollaista diipadaapaa.

Toivottavasti tästä nyt ei tule sellainen kuva että jotenkin suosittelisin mcryptin käyttöä - ei tietenkään, sehän on poistettu käytöstäkin uusimmissa PHP-versioissa. Pointti oli ihan puhtaasti huvitus asian vierestä puhumisesta.

Metabolix [24.06.2019 10:46:00]

#

Millä tavalla tuo alkuperäinen JSON ($body) ja lopullinen JSON eroavat toisistaan? Edellisessä sepustuksessa nähtyjen koodien perusteella samaan lopputulokseen pääsisi jollakin seuraavista riveistä:

$tulos = $body;
$tulos = Zend_Json::encode(array_values(Zend_Json::decode($body)));
$tulos = Zend_Json::encode(array_column(Zend_Json::decode($body), 'id'));

Grez [24.06.2019 11:13:59]

#

Kai siinä oli tarkoitus, että PHP päässä palastellaan siitä vain "yksi sivu" eli 50 tietuetta per pyyntö eteenpäin (jossa tietenkin on todennäköisesti suhteellisen vähän järkeä ja luultavasti (toteutuksesta riippuen) enemmän haittoja kuin hyötyjä)

Metabolix [24.06.2019 11:20:30]

#

Grez, viittasin tuohon jälkimmäisen viestin koodailuun, jossa vain kerätään taulukon id:t silmukassa toiseen taulukkoon $ii-indeksimuuttujalla. Toki tähän voidaan lisätä array_slice joko array_valuen tilalle tai array_columnin ympärille.

walkout_ [28.06.2019 08:59:08]

#

Opinpanhan nyht pari uutta PHP-functiota.

Mutta luulempa, että foreach-silmukkaa on käytettävä silti koska kyseessä on siis Timesheet joka hakee Freshdesk-pilvipalvelusta ensin Tiketit ja niiden tietueet ja sen jälkeen faoreach-silmukan sisällä uusi cURL-kutsu joka hakee tiketeille kaikki käytetyt työtunnit ja laskee ne kalenterimaiseen taulkukkoon yhteen päiväväkohteisesti.

Niin laitoin kyllä enemmän riejäjä per sivu kuin 50. Mutta luulen että ainakin vanhoissa koneissa Ext JS sekoittaa vaan selaimen ja antaa siihen kuuluvia virheilmoituksia jos rivejä yhdelle sivulle haetaan esim. 20000 kpl.

walkout_ [30.06.2019 06:03:46]

#

Eli millaista projektia olen siis tekämssä? No: https://www.i4ware.fi/products/i4ware-timesheet-for-freshdesk/
Ja lähdekoodi tullaan julkaisemaan GNU GPL, v. 3 -lisenssin alla ihan ilmaiseksi.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta