Avatar billede Slettet bruger
20. december 2010 - 16:17 Der er 15 kommentarer og
1 løsning

Finde variabler i en streg med preg_match og gemme disse i et array

Hej

Jeg har hentet indholdet af en php-fil ind i en streng, lad os bare kalde den $test.

$test indeholder et ikke nærmere definerbar antal $_SESSION-variabler, alle med 4 efterfølgende led.

Jeg vil gerne hente alle variabel-navnen ud i et array (ikke indholder af variablerne, men selve variabel-navnene)

Eksempler på hvilke navne en $_SESSION-variabel kan have:
$_SESSION['language']['index.php']['form']['id']
$_SESSION['language']['admin.php']['headline']['welcome']

De har altid 4 led, og første led vil altid være 'language'.

Er der nogen der kan hjælpe mig på vej med hvordan får disse variabler trukket ud af $test.

Årsagen til jeg gerne vil kunne ovenstående, er at jeg har en stor mængde php-filer. Disse php-filer indeholder hver især en masse $_SESSION['language']-variabler. Variablerne anvendes til at vise tekst på hjemmesiden i det sprog brugeren har valgt. Indholdet af alle $_SESSION['language']-variabler bliver sat ud fra nogle værdier i en database.

Jeg skal sikre mig, at der der findes indhold i databasen for alle $_SESSION['language']-variabler der anvendes i disse php-filer, hvilket vil være en kæmpe opgave, hvis jeg skulle åbne alle php-filer og manualt kigge dem igennem for disse variabler.

Ved at få alle anvendte $_SESSION['language']-variabler i et array, vil jeg kunne lave en funktion, der kan kontrollere at der er indhold i databasen for hver variabel.

Samtidig vil jeg kunne lave den modsatte kontrol, altså at der er en variabel for alt indhold i databasen.
Avatar billede groyk Novice
20. december 2010 - 21:12 #1
Måske du kunne bruge noget ala


preg_match_all("|$_SESSION['language'].*?) |si",$test,$out);


Er ikke sikker på at det spiller, har ikke testet.
Avatar billede tjens Nybegynder
20. december 2010 - 22:12 #2
Hvis du kan nøjes med strpos(), substr() og explode() kan det gøres på denne måde:
<?php
$languageSession = '$_SESSION['."'language']";

... loop der skaffer linier fra .php filer

  if ( strpos($line], $languageSession) > -1) {
    list($lang, $page, $type, $name) = explode("']['", $line, 4);
    $name = substr($name, 0, strpos($name, "']"));
    echo ($page . '#' .$type . '#' . $name . '<br>');
  }

... slut loop
}
så kan du gemme værdierne i stedet for echo
Avatar billede Slettet bruger
20. december 2010 - 22:13 #3
Har prøvet ovenstående, men jeg tror der er et eller andet galt med linjen, idet min side går i en HTTP-500 serverfejl når jeg inkluderer linjen på min side.

Nogle forslag?
Avatar billede Slettet bruger
20. december 2010 - 22:21 #4
tjens...> Jeg er lidt i tvivl om hvordan dit loop skal bruges.

Jeg har en .php-fil der er indlæst i variablen $test som en streng. Hvordan skal den benyttes i dit loop?
Avatar billede tjens Nybegynder
20. december 2010 - 22:32 #5
Du kunne ændre fra indlæsning af hele filen til læsning 1 linie ad gangen.

Eller du kan klippe den indlæste streng op i statements med $lines = explode($phpfil, ';')
Avatar billede Slettet bruger
20. december 2010 - 22:52 #6
Har prøvet dette, men output er blankt:


$result = file_get_contents("test.php");
$lines = explode(";", $result);
$languageSession = '$_SESSION['."'language']";
   
foreach ($lines as $value =>$key) {
    $line = $lines[$value];

    if ((strpos($line), $languageSession) > -1) {
        list($lang, $page, $type, $name) = explode("']['", $line, 4);
        $name = substr($name, 0, strpos($name, "']"));
        echo ($page . '#' .$type . '#' . $name . '<br>');
    }
}
Avatar billede tjens Nybegynder
20. december 2010 - 23:15 #7
Nedenstående kan testes her: http://tjens.dk/eksperten/php/test926929.php

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>PHP Explode string arrays</title>
</head>
<body>
<h3>input:</h3>
<p>
<?php
$lines = array ( 'something;',
'$_SESSION['."'language']['index.php']['form']['id']",
'$_SESSION['."'language']['admin.php']['headline']['welcome']",
'Something else;'
);
$count = count($lines);
for ($i = 0; $i<$count; $i++) {
  echo( $i.' : '.$lines[$i].'<br>');
}
?>
</p>
<hr>
<h3>output:</h3>
<p>
<?php
$languageSession = '$_SESSION['."'language']";
for ($i = 0; $i<$count; $i++) {
  if ( strpos($lines[$i], $languageSession) > -1) {
    printVars($lines[$i]);
  }
}

function  printVars($line) {
  list($lang, $page, $type, $name) = explode("']['", $line, 4);
 
  $name = substr($name, 0, strpos($name, "']"));

  echo ($page . '#' .$type . '#' . $name . '<br>') ;
}
?>
</p>
</body>
</html>
Avatar billede Slettet bruger
21. december 2010 - 08:17 #8
Super, det virker som ønsket.

Læg et svar og pointene er dine.
Avatar billede tjens Nybegynder
21. december 2010 - 10:40 #9
Tak for point
Avatar billede Slettet bruger
21. december 2010 - 20:07 #10
Hmm... var vist lige hurtig nok.

Efter at have testet det på en af mine lidt større php-script, er output helt ved siden af.

Nogle idéer til hvad der kan være galt?

Output:

success'] = $_SESSION['language#admin.php#status
firstname'] == "") { $_SESSION['status#error'] .= $_SESSION['language#admin.php
firstname']) > 30) { $_SESSION['status#error'] .= $_SESSION['language#admin.php
lastname'] == "") { $_SESSION['status#error'] .= $_SESSION['language#admin.php
lastname']) > 30) { $_SESSION['status#error'] .= $_SESSION['language#admin.php
company'] == "") { $_SESSION['status#error'] .= $_SESSION['language#admin.php
company']) > 30) { $_SESSION['status#error'] .= $_SESSION['language#admin.php
user_name'] == "") { $_SESSION['status#error'] .= $_SESSION['language#admin.php
user_name']) > 30) { $_SESSION['status#error'] .= $_SESSION['language#admin.php
error'] .= $_SESSION['language#admin.php#error
user_pass'] == "") { $_SESSION['status#error'] .= $_SESSION['language#admin.php
user_pass']) > 30) { $_SESSION['status#error'] .= $_SESSION['language#admin.php
e_mail'] == "") { $_SESSION['status#error'] .= $_SESSION['language#admin.php
e_mail']) > 30) { $_SESSION['status#error'] .= $_SESSION['language#admin.php
e_mail'])) { $_SESSION['status#error'] .= $_SESSION['language#admin.php
error'] .= $_SESSION['language#admin.php#error
comment']) > 50) { $_SESSION['status#error'] .= $_SESSION['language#admin.php
admin_id'] != "") { $_SESSION['status#success'] = $_SESSION['language#admin.php
success'] = $_SESSION['language#admin.php#status
admin.php#form#admin_id
admin.php#form#member_of
system#button#save
system#button#reset
system#button#edit
admin.php#confirm#delete_admin
admin.php#form#firstname
admin.php#form#groups
success'])) { $statusbox = ("

".$_SESSION['language#system#statusbox
admin.php#submenu#show_edit_adm


Min testkode ser sådan her ud:

$result = file_get_contents("admin.php");

$lines = explode(";", $result);
$count = count($lines);

$languageSession = '$_SESSION['."'language']";

for ($i = 0; $i<$count; $i++) {
    if ( strpos($lines[$i], $languageSession) > -1) {
        printVars($lines[$i]);
    }
}

function  printVars($line) {
  list($lang, $page, $type, $name) = explode("']['", $line, 4);
  $name = substr($name, 0, strpos($name, "']"));
  echo ($page . '#' .$type . '#' . $name . '<br>');
}
Avatar billede tjens Nybegynder
21. december 2010 - 22:00 #11
Explode på ";" var et hurtigt indfald fra min side:
Du må kigge på nogle php-filer manuelt, for at spotte om der er bedre måder at klippe din konkrete php op i linier.
"\n" kan måske splitte på de reelle linieskift, hvis det er bedre.


Derudover kan der være andre forekomster af '][' på linien, og det vil sende explode nr 2 helt i hegnet.

Det kan løses ved at sende en substring afsted, i stedet for hele linien:
for ($i = 0; $i<$count; $i++) {
  $lsPos = strpos($lines[$i], $languageSession);
  if ( $lsPos > -1) {
    printVars( substr( $lines[$i], $lsPos + 11 ) );
  }
}

Testsiden har fået tilføjet en linie data, der giver fejlen, og et ekstra afsnit med denne version af loopet, som retter fejlen: http://tjens.dk/eksperten/php/test926929.php
Avatar billede tjens Nybegynder
21. december 2010 - 23:55 #12
Ny og simplere version, der æder sig igennem det lange tekstfelt i stedet for at klippe det op:
$SearchSL = '$_SESSION['."'language']";
$result = file_get_contents("admin.php");

while (  ($slPos = strpos($result, $SearchSL) ) != false ) {

  list($lang, $page, $type, $result ) = explode("']['", substr( $result, $slPos + 11 ), 4);
 
  $name = substr($result, 0, strpos($result, "']"));

  echo ($page . '#' . $type . '#' . $name . '<br>') ;

}
?>

Det er dog stadig strengt nødvendigt at disse session/language forekomster altid har de 4 led.
Avatar billede Slettet bruger
22. december 2010 - 07:54 #13
Jeg er ikke i nærheden af min egen computer før engang i aften, så jeg vender tilbage der efter nærmere test.

Mine $_SESSION['language']-variabler har altid 4 led, så det bliver ikke en showstopper.
Avatar billede Slettet bruger
22. december 2010 - 19:33 #14
Dit sidste forslag kunne jeg ikke få til at virke. Scriptet timede ud.

Dit forslag i #11 virkede derimod efter hensigten.

Igen, tak for hjælpen :)
Avatar billede tjens Nybegynder
23. december 2010 - 13:21 #15
Jeg indrømmer at det er en discountagtig måde at gennemgå programkode på, og der kan forekomme mange former for fejl. F.eks.:
- Der er 2 language session variable i samme linie efter linieopdeling: Den sidste springes over.
- Der er udkommenterede language session variable: De medtages.
- Der er brugt " i stedet for ' et sted: Medtages ikke eller får #12 til at loope.


Hvis det skal være professionelt, skal PHP-filerne parses af en kompiler, så det er reelle brudstykker af programkode der evalueres.

Det vil være muligt hvis du skriver en plugin til denne open source php-compiler: http://www.phpcompiler.org/
Plugin intro:
http://www.phpcompiler.org/doc/latest/traversalintro.html


Hvis du vil fortsætte med mine eksempler, skal du nok udvide med en række kontroller og fejlmeddelelser.
Avatar billede Slettet bruger
25. december 2010 - 22:27 #16
Jeg prøver at få koden modificeret så den vil virke selvom der er 2 language-sessionvariabler i samme linje.

De 2 sidste punkter bliver ikke et problem, idet jeg selv har kodet alle filer og ved at kodningen er udført på samme måde.
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
Vi tilbyder markedets bedste kurser inden for webudvikling

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