Avatar billede N00b Novice
04. september 2016 - 13:04 Der er 26 kommentarer og
2 løsninger

Sqlite query via post giver unrecognized token

Jeg prøver at lave en licens database, som jeg kan kalde via post for at tjekke om en given licens eksistere.

men jeg får en unrecognized token, når jeg prøver at søge licensen via querry.

Min kode ser pt sådan her ud.

[code]
<?php
class MyDB extends SQLite3
  {
      function __construct()
      {
        $this->open('Lic.db');
      }
  }
  $db = new MyDB();
  if(!$db){
      echo $db->lastErrorMsg();
  } else {
      echo "Opened database successfully <br >";
  }

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // collect value of input field
    $lic = $_REQUEST['licens'];
    $prog = $_REQUEST['Prog'];
//$lic = sqlite_escape_string($lic);
  var_dump ($rawSqlQuery);
    $admin = $db->querySingle("SELECT * FROM $prog WHERE LIC=$lic", true);
//$admin = $db->querySingle('SELECT * FROM COPYBOARD WHERE LIC="6046A-FD041-8D31C-BB55D-D0ECA-0BBD8"', true);
var_dump($admin);
}
?>
[/code]

Hvis jeg bruger sqlite_escape_string får jeg intet output, hvis jeg undlader den får jeg unrecognized token

Men hvis jeg "bare" laver en direkte query med manuelt indtastet lic & prog så fungere det fint.

Har prøvet google mm. men syntes ikke jeg har kunne finde en løsning.
Avatar billede arne_v Ekspert
04. september 2016 - 15:38 #1
Hvis $lic ikke er et tal saa:

$admin = $db->querySingle("SELECT * FROM $prog WHERE LIC='$lic'", true);
Avatar billede N00b Novice
04. september 2016 - 16:14 #2
At det var sååå simpelt, syntes ellers at have prøvet alt.

Takker :)

Hvordan sikre jeg mig mod SQL injection når jeg ikke kan bruge escape_string (giver blankt resultat hvis jeg bruger den.)
Avatar billede olsensweb.dk Ekspert
04. september 2016 - 16:37 #3
Avatar billede N00b Novice
04. september 2016 - 17:14 #4
Så min kode skal se sådan her ud i stedet for

<?php
class MyDB extends SQLite3
  {
      function __construct()
      {
        $this->open('Lic.db');
      }
  }
  $db = new MyDB();
  if(!$db){
      echo $db->lastErrorMsg();
  } else {
      echo "Opened database successfully <br >";
  }

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // collect value of input field
    $lic = $_REQUEST['licens'];
    $prog = $_REQUEST['Prog'];
//$lic = sqlite_escape_string($lic);
  var_dump ($rawSqlQuery);
    $admin = $db->prepare("SELECT * FROM (:prog:) WHERE LIC=(:lic:)", true);
$smt->bindValue(':name', $prog, SQLITE3_TEXT);
$smt->bindValue(':email', $lic, SQLITE3_TEXT);
$smt->execute();
//$admin = $db->querySingle('SELECT * FROM COPYBOARD WHERE LIC="6046A-FD041-8D31C-BB55D-D0ECA-0BBD8"', true);
var_dump($admin);
}
?>

Det er første gang jeg arb med php og sqlite.
Avatar billede olsensweb.dk Ekspert
04. september 2016 - 18:54 #5
noget ala
(utested)

<?php
// Create (connect to) SQLite database in file
$db = new PDO('sqlite:Lic.db');
// Set errormode to exceptions
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if ($smt = $db->prepare("SELECT * FROM :prog WHERE LIC=:lic")){
        // collect value of input field
        $lic = $_POST['licens'];
        $prog = $_POST['Prog'];
       
        $smt->bindValue(':prog', $prog, SQLITE3_TEXT);
        $smt->bindValue(':lic', $lic, SQLITE3_TEXT);
        $smt->execute();
        while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
            echo = $row['LIC'];   
        }
       
        var_dump($smt);
    }   
}
?>


nb vær opmærksom på at
extension=php_pdo_sqlite.dll
skal være enablet i din php.ini
Avatar billede olsensweb.dk Ekspert
04. september 2016 - 18:56 #6
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
skal self være
while($row = $smt->fetch(PDO::FETCH_ASSOC)){
for meget copy paste
Avatar billede N00b Novice
05. september 2016 - 05:04 #7
Jeg får ikke noget resultat med ovenstående kode :(

Iflg. min php info så skulle pdo være aktiveret

PDO support    enabled
PDO drivers     pgsql, dblib, mysql, sqlite
Avatar billede olsensweb.dk Ekspert
05. september 2016 - 10:59 #8
er du sikker på dit tabel navn er en parameter ??, det giver nogle problemer når man bruger Prepare Statement, pt bruger jeg ikke Prepare Statement til tabel navnet.

(tested)

<?php
// Create (connect to) SQLite database in file
$db = new PDO('sqlite:Lic.db');
// Set errormode to exceptions
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $prog = $_POST['Prog'];
    if ($smt = $db->prepare("SELECT * FROM $prog WHERE LIC=:lic")){   
        // collect value of input field
        $lic = $_POST['licens'];
        // kort form
        /*
        $array = array(           
            'lic' => $lic
          );
        $smt->execute($array);
        */
        $smt->bindParam(':lic', $lic);
        $smt->execute();
       
        while($row = $smt->fetch(PDO::FETCH_ASSOC)){            
            print_r($row);       
            // echo $row['LIC'];   
        }
    }   
}
?>
<form action="" method="post">
<input type="text" name="licens" value="123">
<input type="text" name="Prog" value="Dogs">
<input type="submit">
</form>



test database (behøver du ikke bruge)
kraftigt inspiraret af http://henryranch.net/software/ease-into-sqlite-3-with-php-and-pdo/

<?php
// Create (connect to) SQLite database in file
$db = new PDO('sqlite:Lic.db');
// Set errormode to exceptions
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec("CREATE TABLE Dogs (Id INTEGER PRIMARY KEY, LIC TEXT, Name TEXT, Age INTEGER)");   
//insert some data...
$db->exec(
    "INSERT INTO Dogs (LIC, Name, Age) VALUES ('123', 'Tank', 2);".
    "INSERT INTO Dogs (LIC, Name, Age) VALUES ('321', 'Glacier', 7); " .
    "INSERT INTO Dogs (LIC, Name, Age) VALUES ('123', 'Ellie', 4);
");
?>


output:

Array
(
    [Id] => 1
    [LIC] => 123
    [Name] => Tank
    [Age] => 2
)
Array
(
    [Id] => 3
    [LIC] => 123
    [Name] => Ellie
    [Age] => 4
)


andre link
http://www.if-not-true-then-false.com/2012/php-pdo-sqlite3-example/
Avatar billede N00b Novice
05. september 2016 - 17:03 #9
Det fungerede :)

Super mange tak for hjælpen, jeg vil studere linksne (igen, har selv fundet dem på et tidligere tidspunkt - men ak ikke forstået hvordan jeg skulle bruge dem.)

Som sagt så er jeg helt ny i det her php /sqlite ting, så om mit tabel navn er en parameter ved jeg ikke, jeg har oprettet tabellen via eksempler fundet på nettet.

Min tanke med det endelige projekt resultat er at man via en side kan taste de informationer som er nødvendige for at generere en licens, disse infos bliver så smidt i databasen via noget insert ting, og licens/brugernavn bliver så echo'ed ud så man kan sende dem til brugeren, og programmer kan så tjekke via post kommandoen om en indtastet licens stemmer overens med den der findes i databasen.

Lige så skal man via siden kunne slette en given licens/bruger - via feks. bruger navnet, hvor man i en dropdown kan vælge hvilket program licensen tilhøre. Så tænker at man der skal lave en query NAME, og så bagefter lave en drop row ting, eller sådan noget.
Avatar billede arne_v Ekspert
05. september 2016 - 17:31 #10
Normalt kan man kun bruge parametre for data vaerdier ikke for navne (hverken tabel navne eller felt navne).
Avatar billede olsensweb.dk Ekspert
05. september 2016 - 17:33 #11
>og så bagefter lave en drop row ting,
du skal nok slette på dens id!!
hvis du sletter på name, skal du have flere ting i din where betingelse for ikke at slette alle dens brugeres records.

drop er en hel tabel.
delete er en/flere row(s)

https://www.sqlite.org/lang_droptable.html
https://www.sqlite.org/lang_delete.html

http://www.tutorialspoint.com/sqlite/sqlite_drop_table.htm
http://www.tutorialspoint.com/sqlite/sqlite_delete_query.htm
Avatar billede olsensweb.dk Ekspert
05. september 2016 - 17:46 #12
#10
hvordan ville du sikre, hvis tabel navnet skal over som variabel/parameter, at der ikke laves grimme ting

denne linje skal sikres
$prog = $_POST['Prog'];

ville du bruge
http://php.net/manual/en/function.sqlite-escape-string.php
$prog = sqlite_escape_string($_POST['Prog']);

eller
http://php.net/manual/en/pdo.quote.php
$prog = $db->quote($_POST['Prog']);
Avatar billede arne_v Ekspert
05. september 2016 - 17:55 #13
@ronols

Hvis parameter ikke er muligt (og det er det normalt ikke for tabel navne), saa maa man jo lave fallback til mere primitive metode.

Jeg er ikke ekspert i SQLite, saa jeg ved ikke hvilken af de to som er bedste. Men jeg ville selv vaelge PDO quote.

To grunde:
- den er database uafhaengig
- den har connection med og dermed kendskab til karakter saet hvilken nogen gange kan vaere vigtig for escape
Avatar billede arne_v Ekspert
05. september 2016 - 18:02 #14
Men jeg er skeptisk overfor designet - i.s.f. et variabelt tabel navn, saa tror jeg at en enkelt tabel med en ekstra kolonne ville vaere bedre.
Avatar billede N00b Novice
05. september 2016 - 18:11 #15
Nu er jeg helt lost :'(
Altså jeg har pt en db, der har en tabel, hvor i der er 3 felter, et id, et navn, og et licens

jeg søger så på licensen, da jeg ved den er unik (bør være) skal slf have lavet et tjek på det også så ikke man kan oprette 2 ens licenser) for hvert bruger.

Data typen for disse er angivet som intg, text og text
Senere skulle der så gerne komme flere tabeller, som er navngivet programnavn - og felterne som den jeg pt har.

Er jeg helt forkert på den, med en sådanne opsætning?
Avatar billede arne_v Ekspert
05. september 2016 - 18:36 #16
Nej. Men du har ikke behov for at saette tabel navn som parameter.
Avatar billede olsensweb.dk Ekspert
05. september 2016 - 18:39 #17
>Men jeg ville selv vaelge PDO quote.
det ville også være min anbefaling
grundet som du skriver "den er database uafhaengig"



>saa tror jeg at en enkelt tabel med en ekstra kolonne ville vaere bedre.
den skal jeg lige have op og vende i hoved.

men skulle man tage tabel navnet med over, skulle tabellerne have ens collonne navne, med mindre collonne navne også kommer med over, i et assoc array, og så er det ved at være langhåret i Prepare Statement


tænker noget ala dette som arne_v lavede i http://www.computerworld.dk/eksperten/spm/1000238?k=8164012 i mysqli


>Er jeg helt forkert på den, med en sådanne opsætning?

jeg ville bygge det op sådan:

tbl_user
id, fornavn, efternavn

tbl_licens
id, user_id, licensnummer

her ville du kunne slette en enkelt licens, uden at slette bruger oplysningerne, og uden at have redundante data.


en bruger kan vel godt have flere licenser eller hvad ??
kan en licens ejes af flere brugere ??
så har vi et mange til mange forhold
Avatar billede N00b Novice
06. september 2016 - 05:06 #18
Ja en bruger kan godt have flere licensen.
Nej der kan ikke være flere brugere om en licens, licensen er unik og bundet op imod brugeren info.

Typisk vil brugeren blive slettet, sammen med licensen.
Avatar billede olsensweb.dk Ekspert
06. september 2016 - 10:24 #19
så kunne din tabel structur ligne den i #17,

eller se sådan ud

tbl_user
id, fornavn, efternavn  (, mail, username, password)

tbl_map_user_program (licens)
id, program_id, user_id / aftale_id(licensnummer) (, antal, gyldig_fra, gyldig_til, noter)

tbl_program
id, name


muligvis også denne tabel, hvis en bruger kan have flere aftaler, (virksomhere der er slået sammen, skiftet navn)
tbl_aftale
id, user_id, aftale nummer



her kan brugeren have lige så mange licenser det skal være (0 til uendelig)
brugeren skal kunne logge ind for at ændre sine stamoplysninger, se sine licenser.

user er her en virksomhed, kunne også være privat person.

program kunne være:
windows 7
windows 8.1
windows 10
office 2007
office 365

men her ville du nok heller ikks sende dit tabel navn med som parameter, for at lave ændringer i din database, senere er der nok nogle af operationerne man kan lave med en generisk CRUD, men det kræver du har en del mere øvelse, og har styr på functioner, eller methoder hvis vi snakker om klasser
lav først operationerne så simpelt og sikkert som muligt, senere kan du se hvad der kan slåes sammen. (så drop det med at tage tabel navnet med som en parameter)
dette
$prog = $_POST['Prog'];
er forbudt i min optik
hvorimod dette
$prog = "Dogs"; // ville kalde variablen $tbl
kunne jeg godt finde på at bruge selv inde i en klasse

jeg tror godt jeg kan se hvad du vil, noget ala

SELECT * FROM windows_7 WHERE LIC=:lic
SELECT * FROM windows_10 WHERE LIC=:lic

men her skyder du dig selv i foden, da du skal lave en ny tabel for hvert program, og tabellerne skal være ens i opbygning, du får meget radundant data


nb: hvad er grunden til du vil bruge sqlite ?? (ud over den ikke kræver en database server)
de flste ville nok anvende en mysql database, her vil der også være flere der kan hjælpe dig, iforhold til sqlite (er også en af de første gange jeg bruger sqlite), hvorimod mysql har brugt rigtig mange gange, og mysql er godt documenteret
Avatar billede N00b Novice
06. september 2016 - 16:06 #20
Hvis jeg bruger en db opsætning som i dit eksempel, hvordan får jeg så sendt program navnet med og den korrekte info retur?

Grunden til at jeg vil bruge sqlite er, som du selv skriver at den er uafhængig af en db server, og jeg der for kan flytte min data fra server til server uden andet at kopiere mappen hvor i det ligger.

Samt at mit arb med at få det til at fungere i php, vil hjælpe mig til at bruge det i mine programmer, da syntax er det samme (næsten) i php som i det script sprog jeg arb i.
Og så troede jeg at den var nemmer at starte med at lære :$.
Avatar billede N00b Novice
06. september 2016 - 16:10 #21
Hmm... Det er da godt at du kan tænke for mig når jeg ikke kan selv :)

Licensen er jo UNIK, så det er kun nødvendigt at sende den via post - så kan php/databasen selv finde resten af informationerne jo :headbang:

Arggg tilbage til tegne bordet så, for så dur det jeg startede med vel ikke til noget :(

... Min db/tabeller behøver dog ikke nær så mange felter da der kun bliver brugt bruger navn, program navn og licens - licensen genereres ud fra brugernavnet.
Avatar billede arne_v Ekspert
06. september 2016 - 16:11 #22
Du kan flytte det hele bare ved at kopiere en mappe. *MEN* hvis du bruger to mapper samtidigt, saa har du to forskellige databaser.
Avatar billede arne_v Ekspert
06. september 2016 - 16:12 #23
Og program navn boer vaere et felt ikke en selvstaendig tabel.

(som jeg allerede var inde paa i #14)
Avatar billede arne_v Ekspert
06. september 2016 - 16:13 #24
Jeg kender heller ikke SQLite, men jeg tror faktisk ikke at der er nogen af emnerne i denne traad som ville vaere anderledes med MySQL.
Avatar billede N00b Novice
07. september 2016 - 04:48 #25
Ja ved godt at hvis jeg bruger 2 mapper samtidig så får jeg 2 forskellige databaser.
Som der også bliver forslået i #19

Nej syntakserne/funktionerne for de to skulle være stort set ens.
Avatar billede olsensweb.dk Ekspert
07. september 2016 - 11:32 #26
#20
>Hvis jeg bruger en db opsætning som i dit eksempel, hvordan får jeg så sendt program navnet med og den korrekte info retur?<
så du anvender ikke program navnet, men dens id.

og lave en dropdown med program navn, og id som value burde ikke volde problemer.

med udgangt punkt i denne mysql database tested i phpmyadmin, sql statement burde være ens.

CREATE TABLE `tbl_map_user_program` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `program_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci COMMENT='licens';

INSERT INTO `tbl_map_user_program` (`id`, `user_id`, `program_id`) VALUES
(1, 1, 1),
(2, 1, 3),
(3, 1, 4),
(4, 1, 6),
(5, 2, 2),
(6, 2, 6);

CREATE TABLE `tbl_program` (
  `id` int(11) NOT NULL,
  `name` varchar(25) COLLATE utf8_danish_ci NOT NULL,
  `noter` varchar(255) COLLATE utf8_danish_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci;

INSERT INTO `tbl_program` (`id`, `name`, `noter`) VALUES
(1, 'windows 7', ''),
(2, 'windows 8.1', ''),
(3, 'windows 10', ''),
(4, 'office 2007', ''),
(5, 'office 2003', ''),
(6, 'office 365', ''),
(7, 'linux fedora', 'kræver ikke licens'),
(8, 'libre office', 'kræver ikke licens');

CREATE TABLE `tbl_user` (
  `id` int(11) NOT NULL,
  `firstname` varchar(25) COLLATE utf8_danish_ci NOT NULL,
  `lastname` varchar(25) COLLATE utf8_danish_ci NOT NULL,
  `licens_no` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci;

INSERT INTO `tbl_user` (`id`, `firstname`, `lastname`, `licens_no`) VALUES
(1, 'Ronny', 'Olsen', 123),
(2, 'test', 'testesen', 369);

ALTER TABLE `tbl_map_user_program`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `tbl_program`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `tbl_user`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `tbl_map_user_program`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;

ALTER TABLE `tbl_program`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;

ALTER TABLE `tbl_user`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;


simpel hvem har user_id 1 ??
SELECT * FROM tbl_user WHERE id=1
simpel hvem har licens_no 123 ??
SELECT * FROM tbl_user WHERE licens_no=123

id, firstname, lastname, licens_no
1 Ronny Olsen 123

hvilke licens pligtige programmer har user_id 1 ??
SELECT tbl_user.*, tbl_program.* FROM tbl_user JOIN tbl_map_user_program ON tbl_user.id = tbl_map_user_program.user_id JOIN tbl_program ON tbl_program.id = tbl_map_user_program.program_id WHERE tbl_user.id=1

id, firstname, lastname, licens_no, id, name, noter
1,Ronny,Olsen,123,1,windows 7,
1,Ronny,Olsen,123,3,windows 10,
1,Ronny,Olsen,123,4,office 2007,
1,Ronny,Olsen,123,6,office 365,

hvem har office 365 ??
SELECT tbl_user.*, tbl_program.* FROM tbl_user JOIN tbl_map_user_program ON tbl_user.id = tbl_map_user_program.user_id JOIN tbl_program ON tbl_program.id = tbl_map_user_program.program_id WHERE tbl_program.id = 6

id,firstname,lastname,licens_no,id,name,noter
1,Ronny,Olsen,123,6,office 365,
2,test,testesen,369,6,office 365,

hvem har en licens pligtig office pakke
SELECT tbl_user.*, tbl_program.* FROM tbl_user JOIN tbl_map_user_program ON tbl_user.id = tbl_map_user_program.user_id JOIN tbl_program ON tbl_program.id = tbl_map_user_program.program_id WHERE tbl_program.id IN (4,5,6)

id,firstname,lastname,licens_no,id,name,noter
1,Ronny,Olsen,123,4,office 2007,
1,Ronny,Olsen,123,6,office 365,
2,test,testesen,369,6,office 365



nb hvis du har en mysql database kørende, kan du få lavet databasen om til sqlite med dette
https://sourceforge.net/projects/mysql2sqlite/

kort tested, med ser lovende ud hvis man er til sqlite

arne_v har sikkert et andet database design i hoved, der også vil virke, men KISS
men tilbage til tegne bordet lav et database design du mener løser opgave, lav nogle test tabeller, og smid nogle test data i, og lav nogle sql statement, og se om du kan få de svar du ønsker.
Avatar billede N00b Novice
08. september 2016 - 05:13 #27
Kan godt se at jeg bliver nød til at løse lidt mere op på brugen af database :)

Var ikke klar over at man i et enkelt query kunne kalde fra flere tabeller :)

Takker rigtigt mange for inputsne.

Jeg er selv tilhænger af KISS modellen, og arb primært selv ud fra den når jeg laver programmer.
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

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