2014-11-25, 23:28
  #1
Medlem
För att hämta information ur en databastabell så kräver mitt skript att särskilda variabler eller kombinationer av variabler existerar och har värden (annars ska något annat ske)

Jag vill därför kunna spara ett uttryck bestående av logiska operatorer i databasen som ett textfält. Uttrycken består av AND, OR och parenteser. Låt säga att det som hämtas ur databasen kräver att variablerna a och (b eller c) har värden:

[PHP]a AND (b OR c)[/PHP]

Jag vill alltså kunna spara uttrycket ovan på ett smart sätt så att det är enkelt att läsa och skapa ett villkor i koden utifrån textfältet. Om jag sparar uttrycket som det är, så blir det ganska besvärligt att läsa, och återskapa villkoret i min kod.

Finns det något smartare sätt att spara logiska uttryck på? Tex som Json, serialiserad array eller liknande. Anda tips?

Jag har svårt för att uttrycka mig, hoppas ni förstår.
Citera
2014-11-26, 06:01
  #2
Medlem
Jag är ledsen men nej, jag förstår inte mycket av det du sa tyvärr.

Kan du försöka förklara en gång till?
Citera
2014-11-26, 10:50
  #3
Medlem
Citat:
Ursprungligen postat av psyninja
Jag är ledsen men nej, jag förstår inte mycket av det du sa tyvärr.

Kan du försöka förklara en gång till?
+1.

Känns som du TS försökt abstrahera problemet vilket gör det svårt för oss att förstå. Det låter bakvänt att spara ett uttryck som ska användas för uthämtning av data.
Citera
2014-11-26, 12:20
  #4
Medlem
Jag gör ett nytt försök. Observera att frågeställningen inte handlar om huruvida det är bästa sättet att angripa ett problem på eller om det känns bakvänt.

Jag vill kunna spara ett logiskt uttryck för att senare i min kod kunna testa om data uppfyller villkoren som beskrivs av uttrycket. Exempel på ett uttryck är A AND B AND (C OR D). Uttrycket skulle kunna representeras av en array som sparas i tex en databas:
[PHP]
$criteria = array();
$criteria["AND"][] = "A";
$criteria["AND"][] = "B";
$criteria["AND"][] = array("OR" => array("C","D"));
[/PHP]

Om jag vill använda uttrycket för att testa om $POST-variabler är satta, dvs att $_POST["A"] och $_POST["B"] och ($_POST["C"] eller $_POST["D"]) har värden, så skulle jag kunna göra det så här:

[PHP]function parseExpression($expression){
global $result;
foreach ($expression AS $operator => $values){
foreach ($values as $value){
if(is_array($value)){
parseExpression($value);
}
elseif(isset($_POST[$value])){
$result[$operator][] = true;
}
else{
$result[$operator][] = false;
}
}
}
}

function validateResult($result){
if(isset($result["AND"]) && in_array(false,$result["AND"])){
return false;
}
if(isset($result["OR"]) && !in_array(true,$result["OR"])){
return false;
}
return true;
}


$result = array();
parseExpression($criteria);

if(validateResult($result)){
echo "Alla variabler som krävs finns";
}else{
echo "Variabler saknas";
}[/PHP]

En annan möjlig lösning skulle kunna vara att helt enkelt spara hela uttrycket
[PHP]isset($_POST["A"]) AND isset($_POST["B"]) AND (isset($_POST["C"]) OR isset($_POST["D"]))[/PHP]
för att senare sedan köra eval() när jag vill använda det.

Jag tycker båda lösningarna är fula och undrar därför om någon har en bättre idé på hur jag bäst sparar ett logiskt uttryck

Citera
2014-11-28, 10:39
  #5
Medlem
Alltså.

Mitt mål är att kunna spara ett kriterium i databas för framtida bruk. Hur kan jag spara, och sedan exekvera ett sparat kriterium på bästa sätt? Ett exempel på kriterium skulle kunna vara:

[PHP]
isset($_POST["a"]) &&
isset($_POST["b"]) &&
(isset($_POST["c"]) || isset($_POST["d"]))
[/PHP]
Citera
2014-11-28, 17:56
  #6
Medlem
Citat:
Ursprungligen postat av AlexanderAnka
Alltså.

Mitt mål är att kunna spara ett kriterium i databas för framtida bruk. Hur kan jag spara, och sedan exekvera ett sparat kriterium på bästa sätt? Ett exempel på kriterium skulle kunna vara:

[PHP]
isset($_POST["a"]) &&
isset($_POST["b"]) &&
(isset($_POST["c"]) || isset($_POST["d"]))
[/PHP]

Menar du att du vill spara koden ovan i en databas och sedan köra eval() på den när du önskar? Varför? Vad är målet med detta? Låter väldigt osäkert och märkligt.
Citera
2014-11-28, 21:23
  #7
Medlem
Citat:
Ursprungligen postat av psyninja
Menar du att du vill spara koden ovan i en databas och sedan köra eval() på den när du önskar? Varför? Vad är målet med detta? Låter väldigt osäkert och märkligt.

Våra kunder kan via ett CMS skapa egna webbformulär. Till formulären kan de knyta olika moduler, tex validering av den data som slutanvändaren fyller i formuläret. I enklaste fallet vill jag förhindra att kunden kan välja modulen "e-postvalidering" om de inte lagt till fältet "e-post" i formuläret.

Jag vill alltså endast att de moduler som fungerar tillsammans med valda formulärfält ska vara valbara, övriga moduler ska inte kunna väljas, eller så ska åtminstone en varning visas om en oförenlig modul väljs.

I fallet med e-post så är det enkelt, men hur och var anger jag bäst att en modul kräver fälten firstname && zip && (lastname || address) eller ännu mer komplexa kriterier?
Citera
2014-11-29, 01:27
  #8
Medlem
Jag skulle spara inställningarna i ett JSON-objekt för varje kund/Inställning och sedan rendera kod beroende på hur värdena är satta i JSON-objektet.

if ($setting['require_validemail']) {
// Kod för att validera email med fältnamn $setting['require_validemail__inputname']
}

Osv osv... En if-sats för varje alternativ. Det blir alltså hårdkodade alternativ.

Kunden kryssar sedan för på en inställningssida:

[x] Require valid email

(om ikryssad så blir $setting['require_validemail'] = true) osv osv...
Citera
2014-11-29, 11:42
  #9
Medlem
Citat:
Ursprungligen postat av psyninja
...
Tack för svar. Jag tror inte ditt förslag uppfyller det mål som jag har. Jag har svårt för att uttrycka mig. men tycker själv att mitt inlägg #7 är tydligast. Ska man läsa endast ett så är det det man ska läsa :-)

Vi skapar ständigt nya moduler, och vill då inte in och hårdkoda något, förutom själva modulen. I databasen sparar vi modulens namn, beskrivning, sökväg till modulen (en fil som inkluderas om modulen är vald) mm. Målet är att i databasen även kunna specificera vilka fält modulen kräver för att kunna exekveras, tex:

Modul1 kräver fälten (a och b och c)
Modul 17 kräver fälten (a och b) eller (c och d)
Modul 99 kräver fälten a och b och (c eller d)
...

Så om kunden har byggt upp ett webbformulär som innehåller fälten a, b och d så ska han endast kunna välja att lägga till modulerna modul 17 och modul 99. Övriga moduler ska inte visas alls, eller så ska där stå en varning "Kan ej väljas, kräver att fälten (a och b och c) ingår i det webbformulär som du skapat"

Vi lägger givetvis även in kontrollen att nödvändiga fält finns, i själva modulen, men för bla användarvänlighetens skull så måste vi förhindra att kunderna överhuvudtaget kan kan välja oförenliga moduler till sina webbformulär. Vi måste även generera varningar om de i efterhand försöker ta bort ett fält från formuläret som krävs av en redan vald modul.
Citera
2014-11-29, 13:46
  #10
Medlem
Vad är en modul? Är det "en mapp med kod"? I grund och botten en klass som implementerar något interface?

Det jag vill komma till är: måste det här "uttrycket" sparas i en databas? Kan det inte finnas en klass per modul för just validering?

Men om du måste spara ner något i en databas, kan det inte motsvara klasser? Då kan du ha AndCondition, Orcondition, RequiredField etc och spara ner som t.ex. json i form av
Kod:
{
   type: 'AndCondition',
   data: {
      left: {
          type: 'RequiredField',
          data: 'a'
      },
      right: {
          type: 'RequiredField',
          data: 'b'
      },
   }
Nu du sen läser upp det bygger du upp klasserna och kör $rootNode->isValid() eller liknande?
Citera
2014-11-29, 14:56
  #11
Medlem
Felpost
__________________
Senast redigerad av Ella-Pella 2014-11-29 kl. 15:22.
Citera
2014-11-29, 15:23
  #12
Medlem
Citat:
Ursprungligen postat av AVGASBARN
Vad är en modul? Är det "en mapp med kod"? I grund och botten en klass som implementerar något interface?
En modul är en fil som inkluderas. Det ser ut ungefär så här på de dynamiska formulärens action-sida:

[PHP]// $selectedModules innehåller endast de moduler kunden valt till detta formulär
foreach($selectedModules as $moduleID){
include("modules/module{$moduleID}.php");
}[/PHP]

I kundernas backend där de väljer moduler, försöker jag få till någonting liknande detta:
[PHP]
// getFormFields returnerar de formulärfält som kunden valt.
// tex firstname, lastname, email etc
$formFields = getFormFields();
while ($row = mysqli_fetch_assoc($resAllModules)) {
//Pudelns kärna. Jag vill kunna spara ett logiskt uttryck
// i "requiredFields" som jag kan jämföra mot $formFields
// för att avgöra om kunden får välja denna modul eller ej.
if(requiredFieldsExist($row["requiredFields"],$formFields)){
echo "<input type='checkbox' value='{$row["moduleID"]}'> {$row["moduleName"]}";
}
else{
echo "{$row["moduleName"]} kan ej väljas eftersom ditt formulär saknar fält som krävs";
}
}
[/PHP]

Mitt problem är hur informationen $row["requiredFields"] ska lagras i databasen och hur funktionen "requiredFieldsExists()" ska byggas upp.

Om jag förstår ditt förslag korrekt så tycker du att jag ska bygga upp varje varje modul som en klass som har en metod requiredFields(). Från backend så itererar jag sedan över samtliga modul-klassfiler, i stil med:
[PHP]if ($handle = opendir('/modules/')) {
while (false !== ($entry = readdir($handle))) {
include("/modules/$entry");
$className = basename($entry);
$module = new $$classname();
if($module->requiredFields($formFields)){
echo "<input type='checkbox' value='{$module->moduleId}'> {$module->modulename}";
}
else{
echo "{$module->modulename} kan ej väljas eftersom ditt formulär saknar fält som krävs";
}

}
closedir($handle);
}[/PHP]

Det kan fungera men ett problem är att jag måste skriva om alla våra hundratals moduler, samt att det intuitivt känns fel att läsa in och instansiera hundratals klasser för att visa tillgängliga moduler, med jag tänker kanske fel där.
Citera
  • 1
  • 2

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in