Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Webprogrammeren & scripting

Functies in PHP

Ger
20 antwoorden
  • In een PHP bestand gebruik ik op 3 plaatsen deze functie:
    [code:1:cb665a1f26] preg_match('#\/([0-9]+)\/index.html#s', $input, $bolid);
    $prdId = $bolid[1];
    preg_match('#>(.*?)</a>#s', $input, $pretitel);
    $titel = $pretitel[1];
    preg_match('#\| <a href=(.*?)>(.*?)</a>#s', $input, $preauteur);
    $auteur = $preauteur[2];[/code:1:cb665a1f26]
    Werkt perfect. Het lijkt me echter handiger (m.n. voor de toekomst) om dit in een functie te proppen, die ik op de gewenste plaatsen include. De functie ziet er zo uit:
    [code:1:cb665a1f26] function boldata($input) {
    preg_match('#\/([0-9]+)\/index.html#s', $input, $bolid);
    $prdId = $bolid[1];
    preg_match('#>(.*?)</a>#s', $input, $pretitel);
    $titel = $pretitel[1];
    preg_match('#\| <a href=(.*?)>(.*?)</a>#s', $input, $preauteur);
    $auteur = $preauteur[2];
    }[/code:1:cb665a1f26]
    en roep ik zo aan:
    [code:1:cb665a1f26] boldata($input2);[/code:1:cb665a1f26]
    Dan gebeurt er echter helemaal niets.

    $input2 is hier hetzelfde als $input in het eerste codeblok. Geef ik een print_r van $input2, dan krijg ik die netjes. Een print_r van $input zou volgens mij hetzelfde moeten geven, maar die is helemaal leeg. De hele functie wordt dus niet uitgevoerd. Wat is de fout?
  • Volgens mij mis je nog een laatste regel met: return $variabele;
    wimb
  • Ja, ik geef dus een print_r(input). Misschien moet ik voor de duidelijkheid iets meer geven:
    [code:1:13c351b91e]
    //Hiervoor wordt de array $matches gevuld. Die is zeker goed (getest).
    $input2 = $matchees[1];
    function boldata($input){
    preg_match('#\/([0-9]+)\/index.html#s', $input, $bolid);
    $prdId = $bolid[1];
    preg_match('#>(.*?)</a>#s', $input, $pretitel);
    $titel = $pretitel[1];
    preg_match('#\| <a href=(.*?)>(.*?)</a>#s', $input, $preauteur);
    $auteur = $preauteur[2];
    }
    boldata($input2);
    print_r($input2); //Klopt als een bus
    print_r($input); //Zo leeg als wat[/code:1:13c351b91e]
    Om de functie te laten werken, moet $input gevuld zijn. Met [b:13c351b91e]boldata($input2);[/b:13c351b91e] vul ik volgens mij [b:13c351b91e]function boldata($input)[/b:13c351b91e] maar blijkbaar toch niet…
  • Als je dit hebt:[b:4c8b84a694]function boldata($input)[/b:4c8b84a694], dan is $input een variabele die alleen in de functie bestaat (daarbuiten dus niet) en daarom altijd leeg is.
    wimb
  • Ok, inderdaad. Als ik de print_r binnen de functie zet, krijg ik wel output. Vraag is dan: hoe krijg ik die 3 variabelen ($prdId, $titel en $auteur) dan eruit zodat ik buiten die functie om ze verder kan behandelen? Want wat er verder mee moet gebeuren verschilt steeds.
  • Het beste is om de output vaneen functie in een return te zetten. Aan het eind van de functie komt dan:
    return array ($prdId, $titel en $auteur);

    de functie aanroepen
    print_r (boldata($input2));

    Je kunt het ook in een array variabele zetten, het ligt er aan wat er verder mee gedaan wordt.
    arrayvar = boldata($input2);

    En een linkje naar functions.returning-values op php.net

    wimb
  • Thanks. Ik heb wat rondgeneusd bij de link die je gaf, en zag daar ook de mogelijkheid staan voor compact en extract, die kende ik nog niet. Wel precies wat ik nodig had. In een stand-alone PHP-script gaat het goed. Hieronder een uitgeklede versie daarvan:
    [code:1:7fffaacbfe]<?php
    //Testmessage, wordt straks in het forum gebruikt dus deze kan na het testen weg
    $message="DVD: <br />
    [dvd]8713045207991[/dvd]<br />
    <br />
    Engels boek & ISBN 10: <br />
    [boek]0099470438[/boek] <br />
    <br />
    Nederlands boek & ISBN 13 <br />
    [boek]9058812774[/boek] <br />
    <br />
    2x totale onzin: <br />
    [dvd]823932474324[/dvd] <br />
    [boek]36482424[/boek] <br />";

    //Deze functie wordt gebruikt voor het opvissen van de product id, de titel en de auteur (=regisseur bij dvd)
    function boldata($input)
    {
    preg_match('#\/([0-9]+)\/index.html#s', $input, $bolid);
    $prdId = $bolid[1];
    preg_match('#>(.*?)</a>#s', $input, $pretitel);
    $titel = $pretitel[1];
    preg_match('#\| <a href=(.*?)>(.*?)</a>#s', $input, $preauteur);
    $auteur = $preauteur[2];
    return compact ('prdId', 'titel', 'auteur');
    }

    /* Hier wat preg_match functies die de BBcode herkent en die koppelt aan de juiste data om gegevens uit te vissen. Levert uiteindelijk de array $matchees op, waarvan $matchees[1] gebruikt wordt. */

    if ($aantalen==0)
    {
    $message = str_ireplace('[boek]'.$isbn.'[/boek]', "[ISBN $isbn onbekend]", $message);
    }
    else
    {
    extract(boldata($matchees[1]));
    //En we maken er iets moois van
    $message= str_ireplace('[boek]'.$isbn.'[/boek]', "<!–start boeklink–><a class=\"postlink\" href=\"http://clk.tradedoubler.com/click?a=$bfMid&p=$siteId&g=$sectionIden&epi=$prdId\" title=\"Bestel via deze link en steun SFB\" alt=\"$titel\" target=\"_blank\"><img src=\"http://img.bol.com/imgbase0/BOOKCOVER/FC/$coverPath$isbn10.gif\" alt=\"$titel\" border=\"0\"><br />$titel<br />$auteur</a><!–einde boeklink–>", $message);

    //Voor stand-alone even echoën, wordt straks door het forum gedaan dus kan op het eind weggehaald worden.
    echo $message;
    ?>
    [/code:1:7fffaacbfe]
    Dat levert uiteindelijk dit op (is testbestandje, dus aan verandering onderhevig). Als ik vervolgens de $message aan het begin en de echo $message aan het eind weghaal en het include in mijn forum (waar de oude variant, zie TS, perfect werkt) dan krijg ik een error die zegt:
    [code:1:7fffaacbfe]Fatal error: Cannot redeclare boldata() (previously declared in /home/swordfac/public_html/forums/bolboek2.php:10) in /home/swordfac/public_html/forums/bolboek2.php on line 19[/code:1:7fffaacbfe]Waarbij regel 10 tot 19 function boldata() is.
    Nu ben ik zover gekomen, en kan ik het niet uitstaan dat het niet lukt, ook al heb ik een werkend alternatief. :)
    Wat kan er fout zijn?
  • Bij mij is het meestal dat de php file met de functie twee maal is ge-include. Een file met een functie mag je maar een maal includen.
    Rename de file met de functie en run dan het programma. Dan komt er een foutmelding van een niet te include file. In die include zet je dan de nieuwe filenaam en weer een run. Komt er nog zo'n foutmelding, dan is er een include teveel en moet die weg.
    wimb
  • Heb ik gedaan, geen uiteindelijk effect. Ik heb het eens getest bij het testforum, daar gaat het wel goed. En dat terwijl ik er toch vrij zeker van ben dat die (buiten de database) 100% identiek is. Blijkbaar toch niet. Inspector Ger goes off to investigate… :lol:

    Dat is echter een andere zoektocht, en daar kom ik vast ook wel weer uit. Heeft echter weinig meer met dit topic te maken, dus rest mij je te bedanken voor de hulp!
  • Wanneer je een bestand hebt met functies zou ik zowiezo include_once() gebruiker in plaats van include(). Op die manier weet je zeker dat het bestand niet meerdere malen ge-include wordt ;)
  • [quote:8fb35d66f7="yendis"]Wanneer je een bestand hebt met functies zou ik zowiezo include_once() gebruiker in plaats van include(). Op die manier weet je zeker dat het bestand niet meerdere malen ge-include wordt ;)[/quote:8fb35d66f7]Dat deed het 'm. :)
    Thanks!
  • Hmm… dat deed het 'm toch niet. Inderdaad wordt het maar 1x geïnclude, en er komen dus geen errors. Als er echter in meerdere berichten op 1 forumpagina die bol-BBcode gebruikt wordt, wordt het alleen in het eerste bericht verwerkt. De rest laat-ie ongemoeid. Da's achteraf ook wel logisch, omdat het [i:a6dd7de396]include_[b:a6dd7de396]once[/b:a6dd7de396][/i:a6dd7de396] is.

    Zou er nog een andere mogelijkheid zijn? Ik heb het nu weer op de ouderwetse manier opgelost, maar dat gaat tegen mijn efficienydrang in. :)
  • Als in het bestand dat je include de functie staat die je gebruikt om de veranderingen toe te passen hoef je deze echt maar 1 keer te includen. Je kan deze functie vervolgens zo vaak aanroepen als je zelf wil en je zou het dus voor alle posts moeten kunnen gebruiken.

    Ik denk daarom dat het probleem niet daar ligt maar ergens anders. Wat je kan doen is kijken of er ergens anders iets fout gaat. Als je de errors nu niet krijgt kun je overwegen om php wat meer informatie over fouten te laten geven (linkje).

    Dus nogmaals, vanaf het moment dat een functie gedefinieerd is kan je deze gebruiken tot het script afgelopen is. de include [b:bb34ff8dd4]ONCE[/b:bb34ff8dd4] heeft dus niets te maken met hoevaak je de functie aan kan roepen.

    Succes
  • je code zal zo'n structuur moeten hebben:

    [code:1:d5ef73a653]<?php
    require_once('bol_function.php')

    for each($rows as $row)
    {
    if()
    {
    // toon onbekend boek
    } else
    {
    extrace(boldata($matchees[1]));
    // toon Bol_book
    }
    }
    ?>[/code:1:d5ef73a653]

    Nog een tip: gebruik array en list ipv compact en extract die als je niet oppast variabelen in je script een andere waarde kunnen geven.
  • [quote:19fa1f148d="yendis"]Als in het bestand dat je include de functie staat die je gebruikt om de veranderingen toe te passen hoef je deze echt maar 1 keer te includen. Je kan deze functie vervolgens zo vaak aanroepen als je zelf wil en je zou het dus voor alle posts moeten kunnen gebruiken.
    (…)
    Dus nogmaals, vanaf het moment dat een functie gedefinieerd is kan je deze gebruiken tot het script afgelopen is. de include [b:19fa1f148d]ONCE[/b:19fa1f148d] heeft dus niets te maken met hoevaak je de functie aan kan roepen.[/quote:19fa1f148d]Mja, maar wat dat betreft vraag ik me even af (heb nog niet de gelegenheid gehad om daar in te duiken) hoe phpBB wat dat betreft werkt. Om een pagina als [b:19fa1f148d]./viewtopic.php[/b:19fa1f148d] op te bouwen worden oa [b:19fa1f148d]./common.php[/b:19fa1f148d], [b:19fa1f148d]./includes/functions_display.php[/b:19fa1f148d], [b:19fa1f148d]./includes/message_parser.php[/b:19fa1f148d] en [b:19fa1f148d]./includes/bbcode.php[/b:19fa1f148d] gebruikt. Ik heb mijn bestand geïnclude in [b:19fa1f148d]bbcode.php[/b:19fa1f148d]. Volgens mij, maar dat weet ik dus niet zeker, wordt [b:19fa1f148d]bbcode.php[/b:19fa1f148d] direct in [b:19fa1f148d]viewtopic.php[/b:19fa1f148d] geïnclude en niet in de message parser. Als dat zo is, dat wordt dus eenmaal geïnclude bij het aanroepen van de pagina en dus blijkbaar maar alleen bij het parsen van het eerste bericht. Bij de volgende berichten wordt het niet meer gebruikt.

    [quote:19fa1f148d="yendis"]Ik denk daarom dat het probleem niet daar ligt maar ergens anders. Wat je kan doen is kijken of er ergens anders iets fout gaat. Als je de errors nu niet krijgt kun je overwegen om php wat meer informatie over fouten te laten geven (linkje).[/quote:19fa1f148d]Thanks, ik zal eens kijken hoe ik dat eenvoudig kan inbouwen.

    [quote:19fa1f148d="marientje"]je code zal zo'n structuur moeten hebben:
    [code:1:19fa1f148d]<?php
    require_once('bol_function.php')

    for each($rows as $row)
    {
    if()
    {
    // toon onbekend boek
    } else
    {
    extrace(boldata($matchees[1]));
    // toon Bol_book
    }
    }
    ?>[/code:1:19fa1f148d][/quote:19fa1f148d]Kun je eens uitleggen waarom?
    [quote:19fa1f148d="marientje"]Nog een tip: gebruik array en list ipv compact en extract die als je niet oppast variabelen in je script een andere waarde kunnen geven.[/quote:19fa1f148d]Kun je dat ook eens uitleggen?

    (sorry voor de misschien irritante vragen, maar het gaat me niet zo zeer om een werkend trucje (wat ik al heb), maar om het onderliggende te begrijpen)
  • [quote:863f8d1558="Ger"](…)Kun je eens uitleggen waarom?[/quote:863f8d1558]
    Ik zie als probleem dat de structuur niet goed: je definieert een functie en vervolgens wil je dat die op alle berichten wordt losgelaten maar het gebeurt maar op 1 bericht. Als ik goed lees ben je phpBB aan het modden, ik heb daar wel ooit wat mee gedaan maar zit daar niet meer in.
    Als zij het goed hadden gedaan, was het nu heel gemakkelijk geweest. De meest simpele structuur om jouw functie op alle berichten los te laten, kan je kortweg schrijven als:

    1) bol_functie definieren (eventueel middels een include)
    2) loopen over alle berichten en
    a) de bolfunctie er op los laten, of
    b) iets anders er mee doen
    en vervolgens dat bericht tonen

    Dit is de meest simpele structuur. Als je volgens simpele principes programmeert, kan het niet fout gaan.
    Nu kan het zijn dat phpBB allemaal andere mooie dingen wil doen, waardoor ze zich hier niet aan houden. In dat geval gaat bovenstaand dus niet op. Je zal dan naar de code (hoogstwaarschijnlijk een loop) op zoek moeten waar wel de berichten worden getoond, daarin zul je je bolfunctie aan het werk moeten zetten.

    [quote:863f8d1558="Ger"][quote:863f8d1558="marientje"]Nog een tip: gebruik array en list ipv compact en extract die als je niet oppast variabelen in je script een andere waarde kunnen geven.[/quote:863f8d1558]Kun je dat ook eens uitleggen?

    (sorry voor de misschien irritante vragen, maar het gaat me niet zo zeer om een werkend trucje (wat ik al heb), maar om het onderliggende te begrijpen)[/quote:863f8d1558]
    Voor vragen en antwoorden is een (dit) forum ;)
    Zoals ik al zei, als je niet oppast en je hebt een array
    [code:1:863f8d1558]
    Array (
    'author' => 'Jan',
    'title' => 'phpBB en bolfuncties',
    'message' => 'deze entry gaat mijn originele message vervangen
    )[/code:1:863f8d1558]
    en je laat in je bolfunctie hier een extract op los, dan zul je zien dat je originele bericht dus vervangen wordt. Als je niet oppast tijdens het programmeren, kunnen hier bugs ontstaan die moeilijk te vinden zijn. Wanneer je extract los laat op $_POST, kunnen gebruikers je script zelfs andere dingen laten doen, dan dat jij wilt dat het deed (met alle gevolgen van dien…).
    Wat jij wilt kan je ook zo bereiken:
    [code:1:863f8d1558]
    function bol_function($input)
    {
    $title = 'Jan';
    $author = 'programmeren en bol functies';
    return array($title, $author);
    }

    list($title, $author) = bol_function('#SOME_INPUT');
    [/code:1:863f8d1558]
    zonder gevaar voor injectie of gevaar voor creeeren van bugs (even afkloppen).
    Als je dit soort dingen van het begin af je zelf aanleert, dan kan er nog maar weinig mis gaan in je coding en is het ook goed leesbaar, duidelijk wat de code nou eigenlijk doet, dus makkelijk herbruikbaar voor jezelf èn anderen.
  • Thanks. Ik had me sowieso al voorgenomen om in de pagina/topic opbouw te duiken, kan ik dat even mooi in het achterhoofd houden.

    V.w.b. de veiligheid: de gebruikers kunnen alleen maar een getallenreeks invoeren binnen de bbcode, anders krijgt de gebruiker een foutmelding en wordt teruggestuurd naar het berichtscherm (beveiliging phpBB) cq wordt de match niet herkend en niet uitgevoerd (beveiliging dmv regexp in mijn code, maar die zou eigenlijk dus al niet nodig hoeven zijn). Het getal wordt ingevuld in een zoekpagina van Bol als paramater voor het ISBN-nummer. Indien dat niet bestaat is de output [b:8c0755c6a7][ISBN {getal} onbekend][/b:8c0755c6a7], bestaat het wel dan wordt de boel met bijbehorende gegevens gegenereerd.
    De $matchees die gebruikt wordt is (zeg ik even uit mijn hoofd) een deel van de sourcecode van de resultatenpagina van Bol, waarin de gegevens staan die ik nodig heb. Daar kan dus in principe ook niets mee fout gaan.
    Wat dat betreft is deze methode wel behoorlijk waterdicht vwb veiligheid denk ik.

    Wel ben ik met je eens dat het in principe een veiliger systeem kan zijn.

    PS: het is inderdaad een modificatie voor phpBB, versie 3.0.x wel te verstaan.
  • Met mijn waarschuwing omtrent compact/extract VS array/list, b-12edoelde ik niet dat je functie niet veilig was. Zoals je al aangaf, gebruikers hebben maar heel weinig mogelijkheden wat er in de vars terecht komt. Maar het is naar mijn mening wel een slechte (lees minder goede) manier van coderen omdat je moeilijk te traceren fouten hier makkelijk maakt.

    Ik heb even gekeken naar viewtopic van phpBB3.x; op regel 1259 -1268 wordt de message geparst. Als je aanroep naar de bolfunctie in bbcode_second_pass gebeurt, dan zou het vanzelf goed moeten gaan voor alle posts. Post eventueel eens wat meer code; of geef een linkje om lappen tekst hier te voorkomen.
  • Weet je zeker dat je de juiste versie van phpBB hebt? Origineel begint dat op lijn 1266 (bij mij door andere mods op 1314).

    Wat ik heb gedaan is het includen in bbcode.php, aan het einde van de functie bbcode_second_pass net boven
    [code:1:66b2213237]// Remove the uid from tags that have not been transformed into HTML
    $message = str_replace(':' . $this->bbcode_uid, '', $message);[/code:1:66b2213237]
    Je zou dus verwachten dat het goed moet gaan, maar dat gaat het dus niet.
  • ik had inderdaad een oudere versie. Het probleem is volgens mij dat de bbcode_bitfield roet in het eten gooit. Wanneer die niet goed staat, wordt jouw de bbcode_second_pass nooit aangeroepen en dus jouw bol_functie ook nooit uitgevoerd. Hoe dat ding echter precies werkt weet ik niet, ik denk dat je flink aan t Googlen moet.
    Wat ook kan, is je bolfunctie niet in bbcode zetten, maar in viewtopic, net nadat second_pass is aangeroepen (en dus voor bbcode_nl2br en smiley_text).
    (Als je naar de grote lijn kijkt zie je dan precies de eerder voorgestelde structuur; voor elke post: pas bol_functie toe en toon, naast dus andere standaardzaken van phpbb zelf)

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.