php / mysql calcolo prezzo base preventivo per hotel

marco4001

Utente Attivo
28 Mar 2008
30
0
0
Salve a tutti ho il seguente problema, spero possiate aiutarmi, devo realizzare un applicativo php/mysql per un hotel che faccia un preventivo. ho la seguente tabella:

http://www.friulisitiweb.it/preventivo/tabellina.jpg

in pratica tramite un form l'utenza inserisce la data di arrivo - check in - (colonna mese e colonna giorno) e la data di partenza - check out - bisogna calcolare il prezzo totale in base alla colonna tipologia di pensione (che ha per ogni periodo un prezzo differente) moltiplicata x il numero di giorni di permanenza.

la mia domanda e':

posto che ci saranno da fare nella tabella delle query select count, select sum between, come posso impostare nella maniera migliore queste query (in PHP) e sopratutto la tabella/e mysql? che posso cmq modificare, non e' detto che debba avere la stessa impostazione di questa.

Grazie
 
ciao,

ho un esempio semplice, che potrebbe consentirti di inserire 1 riga nel tuo php per ottenere il risultato voluto

la tua tabellina è sintetizzata per un'unica tipologia di prezzo in questo modo, (ma puoi aggiungere + prezzi)

Codice:
15/03/2014	85
01/04/2014	100
15/04/2014	110
01/05/2014	80
07/05/2014	70
15/05/2014	90

questa è la tabella nel db a cui puoi aggiungere tutti i prezzi che vuoi

Codice:
CREATE TABLE roomprices
(
  idhotel     int       NOT NULL,
  room        int       NOT NULL,
  price_start datetime  NOT NULL,
  price_end   datetime  NOT NULL,
  price       float     NOT NULL
)

queste sono le insert per le prove (completate di tutti i prezzi inseriti) che volendo estendere puoi duplicare

Codice:
insert into roomprices values (1, 1, '2014/03/15', '2014/03/31', 85)
insert into roomprices values (1, 1, '2014/04/01', '2014/04/14', 100)
insert into roomprices values (1, 1, '2014/04/15', '2014/04/30', 110)
insert into roomprices values (1, 1, '2014/05/01', '2014/05/06', 80)
insert into roomprices values (1, 1, '2014/05/07', '2014/05/14', 70)
insert into roomprices values (1, 1, '2014/05/15', '2014/05/31', 90)

questa è la query da includere in un'unico comando sql,

le costanti contenute nelle set sono i 4 parametri da dare alla query
vanno sostituite con 4 variabili php, null'altro è dovuto, esempio
Codice:
$sql.="set @data_partenza = '" . $DataPartenza . "'";

Codice:
declare @idhotel  as int;
declare @room  as int;
declare @data_arrivo  as datetime;
declare @data_partenza as datetime;

set @idhotel = 1;
set @room    = 1;
set @data_arrivo   = '2014/04/04';
set @data_partenza = '2014/04/17';

select sum(A.TotalDays) as TotalDays, sum(A.TotalCost) as TotalCost from (
select
  1 as tipo
, price_start
, price_end 
, @data_arrivo as arrivo
, @data_partenza as partenza
, CASE WHEN @data_partenza <= price_end 
    THEN DATEDIFF(day, @data_arrivo, @data_partenza) 
    ELSE DATEDIFF(day, @data_arrivo, price_end) + 1
  END as TotalDays
, price
, price * ( 
    CASE WHEN @data_partenza <= price_end 
      THEN DATEDIFF(day, @data_arrivo, @data_partenza) 
      ELSE DATEDIFF(day, @data_arrivo, price_end) + 1
    END ) as TotalCost
from roomprices
where idhotel=@idhotel and room=@room
and @data_arrivo>=price_start and @data_arrivo<=price_end

union

select
  2 as tipo
, price_start
, price_end
, @data_arrivo as arrivo
, @data_partenza as partenza
, DATEDIFF(day, price_start, @data_partenza) as TotalDays
, price
, price * ( DATEDIFF(day, price_start, @data_partenza) ) as TotalCost
from roomprices
where idhotel=@idhotel and room=@room
and @data_partenza>=price_start and @data_partenza<=price_end and @data_arrivo<price_start
 
union

select
  3 as tipo
, price_start
, price_end
, @data_arrivo as arrivo
, @data_partenza as partenza
, 1+DATEDIFF(day, price_start, price_end) as TotalDays
, price 
, price * ( 1+DATEDIFF(day, price_start, price_end) ) as TotalCost
from roomprices 
where idhotel=@idhotel and room=@room
and price_start>@data_arrivo and price_end<@data_partenza
) A

la si spiega abbastanza facilmente,

la prima select somma i valori trovati fornendo il risultato,

poi ci sono 3 select in union che forniscono risultati dello stesso tipo per essere tra loro congruenti,

la prima (tipo = 1) estrae i valori dalla data di arrivo,

la seconda (tipo = 2) estrae i valori dalla data di partenza

la terza (tipo = 3) eventuali intermedi tra le due date (arrivo / partenza)

non è detto che lavorino tutte e 3,
potrebbe lavorare solo la prima
o la prima e la seconda
mentre per periodi lunghi o con frequenti cambi di prezzo potrebbero lavorare tutte e 3
(vedi Natale, Pasqua, weekend a tema ... e la fantasia non si ferma mai)

per vederla lavorare si possono togliere le due righe
Codice:
select sum(A.TotalDays) as TotalDays, sum(A.TotalCost) as TotalCost from (
) A
permettendo così di vedere le estrazioni che vengono fatte

nota bene, la data di partenza non è conteggiata e le date devono essere in formato aaaa/mm/gg per evitare problemi

per adattarla alla tua ricerca senza cambiarla, metterei una colonna prezzo, "nome_di_riferimento", nella query,
e quando la variabile php che la contiene, è pronta, con un rimpiazza cambi il nome della colonna del prezzo
PHP:
str_replace("nome_di_riferimento", "nome_vero", $sql);
(mi sembra si scriva così)
in modo da scegliere la tipologia di pensione adatta al momento
("nome_vero" sarà in realtà la variabile php che conterrà il nome giusto della colonna da usare per la ricerca)

ho scritto molto ma, non mi sembra complicato

PROBLEMA è funzionante con MS SQL spero tu la possa adattare (nel caso fosse necessario) x mySQL
la parte che potrebbe avere differenze di scrittura

Codice:
  CASE WHEN @data_partenza <= price_end 
    THEN DATEDIFF(day, @data_arrivo, @data_partenza) 
    ELSE DATEDIFF(day, @data_arrivo, price_end) + 1
  END as TotalDays

buon lavoro
Marino

ps ti posto anche lo script php

PHP:
<?php

# http://localhost/test_site/php/test/FormazionePrezzo.php

require '../includes/Config_DB.php';

$idhotel = 1;
$room    = 1;
$DataArrivo  = '2014/04/04';
$DataPartenza= '2014/05/17';
$IDprezzo    = 'price';       // nome della colonna da cercare per tipologia di pensione

$sql = PreparaSql($idhotel, $room, $DataArrivo, $DataPartenza, $IDprezzo);

$data = $db->Query_select($sql);
$dbresult = count($data);
if ($dbresult) {
  $TotalDays = $data[0][0];
  $TotalCost = $data[0][1];
  print "Hotel     : " . $idhotel      . "<br /> 
         Camera    : " . $room         . "<br />
         Pensione  : " . $IDprezzo     . "<br />
         Arrivo    : " . $DataArrivo   . "<br />
         Partenza  : " . $DataPartenza . "<br />
         TotalDays : " . $TotalDays    . "<br /> 
         TotalCost : " . $TotalCost    . "<br />";
}

function PreparaSql($idhotel='', $room='', $DataArrivo='', $DataPartenza='', $IDprezzo='') {

  // inserire eventuali controlli di validità sui parametri se non fatti prima

  $sql = "declare @idhotel as int;";
  $sql.= "declare @room    as int;";
  $sql.= "declare @data_arrivo   as datetime;";
  $sql.= "declare @data_partenza as datetime;";

  $sql.= "set @idhotel = " . $idhotel . ";";
  $sql.= "set @room    = " . $room    . ";";
  $sql.= "set @data_arrivo   = '" . $DataArrivo   . "';";
  $sql.= "set @data_partenza = '" . $DataPartenza . "';";

  $sql.= "select sum(A.TotalDays) as TotalDays, sum(A.TotalCost) as TotalCost from (";
  $sql.= "select";
  $sql.= "  1 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", CASE WHEN @data_partenza <= price_end";
  $sql.= "    THEN DATEDIFF(day, @data_arrivo, @data_partenza)";
  $sql.= "    ELSE DATEDIFF(day, @data_arrivo, price_end) + 1";
  $sql.= "  END as TotalDays";
  $sql.= ", COLPREZZO";
  $sql.= ", COLPREZZO * (";
  $sql.= "    CASE WHEN @data_partenza <= price_end";
  $sql.= "      THEN DATEDIFF(day, @data_arrivo, @data_partenza)";
  $sql.= "      ELSE DATEDIFF(day, @data_arrivo, price_end) + 1";
  $sql.= "    END ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and @data_arrivo>=price_start and @data_arrivo<=price_end";

  $sql.= " union ";

  $sql.= "select";
  $sql.= "  2 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", DATEDIFF(day, price_start, @data_partenza) as TotalDays";
  $sql.= ", COLPREZZO";
  $sql.= ", COLPREZZO * ( DATEDIFF(day, price_start, @data_partenza) ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and @data_partenza>=price_start and @data_partenza<=price_end and @data_arrivo<price_start";
 
  $sql.= " union ";

  $sql.= "select";
  $sql.= "  3 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", 1+DATEDIFF(day, price_start, price_end) as TotalDays";
  $sql.= ", COLPREZZO";
  $sql.= ", COLPREZZO * ( 1+DATEDIFF(day, price_start, price_end) ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and price_start>@data_arrivo and price_end<@data_partenza";
  $sql.= ") A";

  return str_replace("COLPREZZO", $IDprezzo, $sql);
}
?>
 
Ultima modifica:
Ti ringrazio veramente molto, ho solo un dubbio, in pratica tu hai, eliminato la tipologia di prezzo basata sul tipo di pensione, e differenziando il prezzo solo per la data del soggiorno, e' corretto?
 
Ti ringrazio veramente molto, ho solo un dubbio, in pratica tu hai, eliminato la tipologia di prezzo basata sul tipo di pensione, e differenziando il prezzo solo per la data del soggiorno, e' corretto?

non ho assolutamente eliminato la tipologia di prezzo basata sul tipo di pensione, la ottengo fornendo alla query la colonna su cui fare il calcolo, vedi "str_replace", è vero che posso calcolare una tipologia per volta, ma se volessi più tipologie, posso eseguire la query più volte fornendo ogni volta il nome della colonna che contiene il prezzo attraverso la variabile $IDprezzo

ovvero supponendo di avere le tue 3 colonne di prezzo chiamate "completa", "mezza" e "pernottamento",
fornirai alla query il nome della colonna su cui vuoi fare il calcolo esempio $IDprezzo = "completa" oppure $IDprezzo = "mezza" o da buon ultimo $IDprezzo = "pernottamento"

il vero limite se vuoi è costituito dal fatto che i prezzi si muovono con il periodo, ma lo hai scritto nella tua tabellina,
definisci un solo periodo da/a con 3 prezzi altrimenti avresti 3 tabelline differenti

ciao
Marino
 
Ultima modifica:
ho modificato la tabellina nel db aggiungengo altre colonne prezzi (vedi figura)
ho modificato il nome della colonna nella chiamata
"$sql = PreparaSql(......)" con il seguente risultato

Hotel : 1
Camera : 1
Pensione : pensionecompleta
Arrivo : 2014/04/04
Partenza : 2014/05/17
TotalDays : 43
TotalCost : 4080.0

Hotel : 1
Camera : 1
Pensione : mezzapensione
Arrivo : 2014/04/04
Partenza : 2014/05/17
TotalDays : 43
TotalCost : 3300.0

Hotel : 1
Camera : 1
Pensione : pernottamento
Arrivo : 2014/04/04
Partenza : 2014/05/17
TotalDays : 43
TotalCost : 2560.0

(per controllo vedi figuara excel)

In questo modo abbiamo verificato il funzionamento delle 3 select
ma solo in modo parziale per la prima

Hotel : 1
Camera : 1
Pensione : pernottamento
Arrivo : 2014/04/04
Partenza : 2014/04/11
TotalDays : 7
TotalCost : 420.0

il pernottamento è di 60 per il perodo selezionato ovvero 7 * 60 = 420
con questo abbiamo controllato il funzionamento completo della prima select

per altri dubbi, fatti vivo
ciao
Marino

FormazionePrezzo1.PNG

FormazionePrezzo2.PNG
 
ok, capito un immenso grazie

solo una raccomandazione, perché ti ho visto in affanno con le date (precedenti post),
nelle query, metti sempre le date nel formato aaaa/mm/gg,
non sapendo qual è il default del db, in questo modo ho sempre evitato che una data
03/04/2014 venisse interpretata come 4 marzo 2014 !!
ciao
Marino

ps, ti sarai già reso conto che in questo modo puoi avere molte colonne prezzo diverse per finalità ...
esempio la colonna "listino sposi" ... ma ancora la fantasia ....
le calcoli una per volta ma ... le calcoli, cambiando un solo nome !
ciao
 
Ultima modifica:
ciao ho provato il tuo script ma mi genera un errore:
Codice:
Fatal error: Call to a member function Query_select() on a non-object in /web/htdocs/www.MIOSITO.IT/home/test/prova.php on line 23
ti posto il codice che ho inserito:
Codice:
<?php

# http://localhost/test_site/php/test/FormazionePrezzo.php

// mi connetto al database
include "connetti.php";

$idhotel = 1;
$room    = 1;
$DataArrivo  = '2014/04/04';
$DataPartenza= '2014/05/17';
$IDprezzo    = 'price';       // nome della colonna da cercare per tipologia di pensione

$sql = PreparaSql($idhotel, $room, $DataArrivo, $DataPartenza, $IDprezzo);

$data = $db->Query_select($sql);
$dbresult = count($data);
if ($dbresult) {
  $TotalDays = $data[0][0];
  $TotalCost = $data[0][1];
  print "Hotel     : " . $idhotel      . "<br /> 
         Camera    : " . $room         . "<br />
         Pensione  : " . $IDprezzo     . "<br />
         Arrivo    : " . $DataArrivo   . "<br />
         Partenza  : " . $DataPartenza . "<br />
         TotalDays : " . $TotalDays    . "<br /> 
         TotalCost : " . $TotalCost    . "<br />";
}

function PreparaSql($idhotel='', $room='', $DataArrivo='', $DataPartenza='', $IDprezzo='') {

  // inserire eventuali controlli di validità sui parametri se non fatti prima

  $sql = "declare @idhotel as int;";
  $sql.= "declare @room    as int;";
  $sql.= "declare @data_arrivo   as datetime;";
  $sql.= "declare @data_partenza as datetime;";

  $sql.= "set @idhotel = " . $idhotel . ";";
  $sql.= "set @room    = " . $room    . ";";
  $sql.= "set @data_arrivo   = '" . $DataArrivo   . "';";
  $sql.= "set @data_partenza = '" . $DataPartenza . "';";

  $sql.= "select sum(A.TotalDays) as TotalDays, sum(A.TotalCost) as TotalCost from (";
  $sql.= "select";
  $sql.= "  1 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", CASE WHEN @data_partenza <= price_end";
  $sql.= "    THEN DATEDIFF(day, @data_arrivo, @data_partenza)";
  $sql.= "    ELSE DATEDIFF(day, @data_arrivo, price_end) + 1";
  $sql.= "  END as TotalDays";
  $sql.= ", price";
  $sql.= ", price * (";
  $sql.= "    CASE WHEN @data_partenza <= price_end";
  $sql.= "      THEN DATEDIFF(day, @data_arrivo, @data_partenza)";
  $sql.= "      ELSE DATEDIFF(day, @data_arrivo, price_end) + 1";
  $sql.= "    END ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and @data_arrivo>=price_start and @data_arrivo<=price_end";

  $sql.= " union ";

  $sql.= "select";
  $sql.= "  2 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", DATEDIFF(day, price_start, @data_partenza) as TotalDays";
  $sql.= ", price";
  $sql.= ", price * ( DATEDIFF(day, price_start, @data_partenza) ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and @data_partenza>=price_start and @data_partenza<=price_end and @data_arrivo<price_start";
 
  $sql.= " union ";

  $sql.= "select";
  $sql.= "  3 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", 1+DATEDIFF(day, price_start, price_end) as TotalDays";
  $sql.= ", price";
  $sql.= ", price * ( 1+DATEDIFF(day, price_start, price_end) ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and price_start>@data_arrivo and price_end<@data_partenza";
  $sql.= ") A";

// price é la colonna del prezzo

  return str_replace("price", $IDprezzo, $sql);
}
?>

questa e' la tabella mysql

Codice:
CREATE TABLE IF NOT EXISTS `roomprices` (
  `idhotel` int(11) NOT NULL,
  `room` int(11) NOT NULL,
  `price_start` datetime NOT NULL,
  `price_end` datetime NOT NULL,
  `price` float NOT NULL,
  KEY `idhotel` (`idhotel`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Dump dei dati per la tabella `roomprices`
--

INSERT INTO `roomprices` (`idhotel`, `room`, `price_start`, `price_end`, `price`) VALUES
(1, 1, '2014-03-15 00:00:00', '2014-03-31 00:00:00', 85),
(1, 1, '2014-04-04 00:00:00', '2014-04-14 00:00:00', 100),
(1, 1, '2014-05-01 00:00:00', '2014-05-06 00:00:00', 80),
(1, 1, '2014-05-07 00:00:00', '2014-05-14 00:00:00', 70),
(1, 1, '2014-05-15 00:00:00', '2014-05-31 00:00:00', 90);
 
hai inserito,
PHP:
// mi connetto al database
include "connetti.php";

ora devi adattare anche la lettura del db, in funzione della tua connessione (io ho definito una mia classe per l'accesso al db)
PHP:
$data = $db->Query_select($sql);

ciao
Marino
 
ti suggerisco di modificare la tabella in modo che sia già pronta per l'uso che ne devi fare
sistemando anche l'indice di ricerca, mettere solo "hotel" come indice equivale a non mettere nulla

CREATE TABLE IF NOT EXISTS `roomprices` (
`idhotel` int(11) NOT NULL,
`room` int(11) NOT NULL,
`price_start` datetime NOT NULL,
`price_end` datetime NOT NULL,
`pensionecompleta` float NOT NULL,
`mezzapensione` float NOT NULL,
`pernottamento` float NOT NULL,
KEY `index1` (`idhotel`, `room`, `price_start`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


aggiusta poi le insert
ciao
 
mi potresti postare il nome della classe? - e' l'ultima cosa che ti chiedo

se vuoi il nome della classe per cercarla e scaricarla, mi spiace, la classe è nata da "Luigi777", l'ho ripresa da un suo post ed adattata con quello che mi interessava e piaceva, se cerchi i suoi post, troverai tutto

in ogni caso trovi in allegato il file della classe, ripulito e con l'impostazione mysql (copiata da Luigi)

ho cercato di commentarlo, per spiegare le funzioni.

devi inserire, al solito, user e password per l'accesso al db che devi, altrettanto, dichiarare.
attento io preferisco avere i risultati indicizzati per numero non per nome,
nella query dichiaro sempre l'elenco dei campi a scanso di errori che si possono generare anche successivamente
se tu vuoi cambiare puoi sostituire FETCH_NUM con FETCH_ASSOC

e non farti un problema se hai altro che ti interessa,
ciao
Marino

non mi carica il file, lo attacco come codice
PHP:
<?php

error_reporting(E_ALL);

class Database {

  private $db; 

  function __construct(
    $dbPDO  = 'mysql',
    $dbHOST = 'localhost',
    $dbUSER = '',
    $dbPASS = '',
    $dbNAME = ''){ 

    $this->MyLog("");
    $this->MyLog("main : ".basename ($_SERVER['PHP_SELF'],".php").".php");

    try { $this->db = new PDO($dbPDO.":Server=".$dbHOST.";Database=".$dbNAME, $dbUSER, $dbPASS); }
    catch (PDOException $e) { $this->handle_sql_errors("PDO : OPEN DB", $e); }
    $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  } 

  function __destruct() { 
    $this->close(); 
  } 

//esegue una qualunque query, ritorna il risultato conforme alla query stessa
  function Query_exec($sql){
    $this->MyLog("SQL : $sql");
    try { return $this->db->exec($sql); }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e); }
  } 

//select, per estrarre tutti i dati della tabella, ritorna array dei dati con FETCH_NUM
  function Query_select($sql){
    $this->MyLog("SQL : $sql");
    try { $sth = $this->db->prepare($sql); $sth->execute(); return $sth->fetchall(PDO::FETCH_NUM); }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e); }
  } 

//select, per estrarre tutti i dati della tabella, ritorna array dei dati con FETCH_BOTH
  function Query_select_b($sql){
    $this->MyLog("SQL : $sql");
    try { $sth = $this->db->prepare($sql); $sth->execute(); return $sth->fetchall(PDO::FETCH_BOTH); }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e); }
  } 

//prepare -> bind -> execute, query con parametri 
  function Query_bind($sql,
    $par1 ='', $par2 ='', $par3 ='', $par4 ='', $par5 ='', $par6 ='', $par7 ='', $par8 ='', $par9 ='', $par10='',
    $par11='', $par12='', $par13='', $par14='', $par15='', $par16='', $par17='', $par18='', $par19='', $par20=''){

    $this->MyLog("SQL : ".$sql);
    $x = substr_count($sql, "?");
    if ($x > 20) $this->MyErr("ERRORE : la query contiene più di 20 parametri, gestiti fino a 20");
    try {
      $sth = $this->db->prepare($sql); 
      if($x > 0)  { $sth->bindParam(1,  $par1); 
      if($x > 1)  { $sth->bindParam(2,  $par2); 
      if($x > 2)  { $sth->bindParam(3,  $par3); 
      if($x > 3)  { $sth->bindParam(4,  $par4); 
      if($x > 4)  { $sth->bindParam(5,  $par5); 
      if($x > 5)  { $sth->bindParam(6,  $par6); 
      if($x > 6)  { $sth->bindParam(7,  $par7); 
      if($x > 7)  { $sth->bindParam(8,  $par8); 
      if($x > 8)  { $sth->bindParam(9,  $par9); 
      if($x > 9)  { $sth->bindParam(10, $par10); 
      if($x > 10) { $sth->bindParam(11, $par11); 
      if($x > 11) { $sth->bindParam(12, $par12); 
      if($x > 12) { $sth->bindParam(13, $par13); 
      if($x > 13) { $sth->bindParam(14, $par14); 
      if($x > 14) { $sth->bindParam(15, $par15); 
      if($x > 15) { $sth->bindParam(16, $par16); 
      if($x > 16) { $sth->bindParam(17, $par17); 
      if($x > 17) { $sth->bindParam(18, $par18); 
      if($x > 18) { $sth->bindParam(19, $par19); 
      if($x > 19) { $sth->bindParam(20, $par20); } } } } } } } } } } } } } } } } } } } } 
      return $sth->execute(); }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e); }
  } 

  function close(){ 
    unset($this->db); 
  }

//scrive un testo nel log di PHP
  function MyLog($text) {
    error_log($text, 0);		// commentare questa riga se in produzione, no log !
  }

//scrive un errore nel log di PHP e interrompe l'esecuzione
  function MyErr($text) {
    error_log($text, 0);
    print "ERRORE INATTESO, contatta l'amministratore del sistema";
    die;
  }

//gestisce gli errori delle query. vedi setAttribute più sopra
  function handle_sql_errors($sql, $e){
    error_log("SQL cmd    : $sql", 0);
    error_log("error code : ". $e->getCode(), 0);
    error_log("error info : ". $e->getMessage(), 0);
    print "ERRORE INATTESO, contatta l'amministratore del sistema";
    die;
} }  

if (isset($_REQUEST['_SESSION'])) die("Get lost Muppet!");

$db=new Database();
 
Ciao, mi dispiace romperti ancora ma mi da:

Codice:
ERRORE INATTESO, contatta l'amministratore del sistema

ti posto i codici

creazione database
Codice:
CREATE TABLE IF NOT EXISTS `roomprices` (
`idhotel` int(11) NOT NULL,
`room` int(11) NOT NULL,
`price_start` datetime NOT NULL,
`price_end` datetime NOT NULL,
`pensionecompleta` float NOT NULL,
`mezzapensione` float NOT NULL,
`pernottamento` float NOT NULL,
KEY `index1` (`idhotel`, `room`, `price_start`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

script di connessione al database
Codice:
<?php

error_reporting(E_ALL);

class Database {

  private $db; 

  function __construct(
    $dbPDO  = 'mysql',
    $dbHOST = 'indirizzo ip',
    $dbUSER = 'nome utente',
    $dbPASS = 'password',
    $dbNAME = 'dbname'){ 

    $this->MyLog("");
    $this->MyLog("main : ".basename ($_SERVER['PHP_SELF'],".php").".php");

    try { $this->db = new PDO($dbPDO.":Server=".$dbHOST.";Database=".$dbNAME, $dbUSER, $dbPASS); }
    catch (PDOException $e) { $this->handle_sql_errors("PDO : OPEN DB", $e); }
    $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  } 

  function __destruct() { 
    $this->close(); 
  } 

//esegue una qualunque query, ritorna il risultato conforme alla query stessa
  function Query_exec($sql){
    $this->MyLog("SQL : $sql");
    try { return $this->db->exec($sql); }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e); }
  } 

//select, per estrarre tutti i dati della tabella, ritorna array dei dati con FETCH_NUM
  function Query_select($sql){
    $this->MyLog("SQL : $sql");
    try { $sth = $this->db->prepare($sql); $sth->execute(); return $sth->fetchall(PDO::FETCH_NUM); }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e); }
  } 

//select, per estrarre tutti i dati della tabella, ritorna array dei dati con FETCH_BOTH
  function Query_select_b($sql){
    $this->MyLog("SQL : $sql");
    try { $sth = $this->db->prepare($sql); $sth->execute(); return $sth->fetchall(PDO::FETCH_BOTH); }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e); }
  } 

//prepare -> bind -> execute, query con parametri 
  function Query_bind($sql,
    $par1 ='', $par2 ='', $par3 ='', $par4 ='', $par5 ='', $par6 ='', $par7 ='', $par8 ='', $par9 ='', $par10='',
    $par11='', $par12='', $par13='', $par14='', $par15='', $par16='', $par17='', $par18='', $par19='', $par20=''){

    $this->MyLog("SQL : ".$sql);
    $x = substr_count($sql, "?");
    if ($x > 20) $this->MyErr("ERRORE : la query contiene più di 20 parametri, gestiti fino a 20");
    try {
      $sth = $this->db->prepare($sql); 
      if($x > 0)  { $sth->bindParam(1,  $par1); 
      if($x > 1)  { $sth->bindParam(2,  $par2); 
      if($x > 2)  { $sth->bindParam(3,  $par3); 
      if($x > 3)  { $sth->bindParam(4,  $par4); 
      if($x > 4)  { $sth->bindParam(5,  $par5); 
      if($x > 5)  { $sth->bindParam(6,  $par6); 
      if($x > 6)  { $sth->bindParam(7,  $par7); 
      if($x > 7)  { $sth->bindParam(8,  $par8); 
      if($x > 8)  { $sth->bindParam(9,  $par9); 
      if($x > 9)  { $sth->bindParam(10, $par10); 
      if($x > 10) { $sth->bindParam(11, $par11); 
      if($x > 11) { $sth->bindParam(12, $par12); 
      if($x > 12) { $sth->bindParam(13, $par13); 
      if($x > 13) { $sth->bindParam(14, $par14); 
      if($x > 14) { $sth->bindParam(15, $par15); 
      if($x > 15) { $sth->bindParam(16, $par16); 
      if($x > 16) { $sth->bindParam(17, $par17); 
      if($x > 17) { $sth->bindParam(18, $par18); 
      if($x > 18) { $sth->bindParam(19, $par19); 
      if($x > 19) { $sth->bindParam(20, $par20); } } } } } } } } } } } } } } } } } } } } 
      return $sth->execute(); }
    catch(PDOException $e){ $this->handle_sql_errors($sql, $e); }
  } 

  function close(){ 
    unset($this->db); 
  }

//scrive un testo nel log di PHP
  function MyLog($text) {
    error_log($text, 0);        // commentare questa riga se in produzione, no log !
  }

//scrive un errore nel log di PHP e interrompe l'esecuzione
  function MyErr($text) {
    error_log($text, 0);
    print "ERRORE INATTESO, contatta l'amministratore del sistema";
    die;
  }

//gestisce gli errori delle query. vedi setAttribute più sopra
  function handle_sql_errors($sql, $e){
    error_log("SQL cmd    : $sql", 0);
    error_log("error code : ". $e->getCode(), 0);
    error_log("error info : ". $e->getMessage(), 0);
    print "ERRORE INATTESO, contatta l'amministratore del sistema";
    die;
} }  

if (isset($_REQUEST['_SESSION'])) die("Get lost Muppet!");

$db=new Database(); ?>

script di elaborazione
Codice:
<?php

    # http://localhost/test_site/php/test/FormazionePrezzo.php

require 'Config_DB.php';

    $idhotel = 1;
    $room    = 1;
    $DataArrivo  = '2014/04/04';
    $DataPartenza= '2014/05/17';
    $IDprezzo    = 'pernottamento';       // nome della colonna da cercare per tipologia di pensione

    $sql = PreparaSql($idhotel, $room, $DataArrivo, $DataPartenza, $IDprezzo);

    $data = $db->Query_select($sql);
    $dbresult = count($data);
    if ($dbresult) {
      $TotalDays = $data[0][0];
      $TotalCost = $data[0][1];
      print "Hotel     : " . $idhotel      . "<br /> 
             Camera    : " . $room         . "<br />
             Pensione  : " . $IDprezzo     . "<br />
             Arrivo    : " . $DataArrivo   . "<br />
             Partenza  : " . $DataPartenza . "<br />
             TotalDays : " . $TotalDays    . "<br /> 
             TotalCost : " . $TotalCost    . "<br />";
    }

    function PreparaSql($idhotel='', $room='', $DataArrivo='', $DataPartenza='', $IDprezzo='') {

      // inserire eventuali controlli di validità sui parametri se non fatti prima

      $sql = "declare @idhotel as int;";
      $sql.= "declare @room    as int;";
      $sql.= "declare @data_arrivo   as datetime;";
      $sql.= "declare @data_partenza as datetime;";

      $sql.= "set @idhotel = " . $idhotel . ";";
      $sql.= "set @room    = " . $room    . ";";
      $sql.= "set @data_arrivo   = '" . $DataArrivo   . "';";
      $sql.= "set @data_partenza = '" . $DataPartenza . "';";

      $sql.= "select sum(A.TotalDays) as TotalDays, sum(A.TotalCost) as TotalCost from (";
      $sql.= "select";
      $sql.= "  1 as tipo";
      $sql.= ", price_start";
      $sql.= ", price_end";
      $sql.= ", @data_arrivo as arrivo";
      $sql.= ", @data_partenza as partenza";
      $sql.= ", CASE WHEN @data_partenza <= price_end";
      $sql.= "    THEN DATEDIFF(day, @data_arrivo, @data_partenza)";
      $sql.= "    ELSE DATEDIFF(day, @data_arrivo, price_end) + 1";
      $sql.= "  END as TotalDays";
      $sql.= ", pernottamento";
      $sql.= ", pernottamento * (";
      $sql.= "    CASE WHEN @data_partenza <= price_end";
      $sql.= "      THEN DATEDIFF(day, @data_arrivo, @data_partenza)";
      $sql.= "      ELSE DATEDIFF(day, @data_arrivo, price_end) + 1";
      $sql.= "    END ) as TotalCost";
      $sql.= " from roomprices";
      $sql.= " where idhotel=@idhotel and room=@room";
      $sql.= " and @data_arrivo>=price_start and @data_arrivo<=price_end";

      $sql.= " union ";

      $sql.= "select";
      $sql.= "  2 as tipo";
      $sql.= ", price_start";
      $sql.= ", price_end";
      $sql.= ", @data_arrivo as arrivo";
      $sql.= ", @data_partenza as partenza";
      $sql.= ", DATEDIFF(day, price_start, @data_partenza) as TotalDays";
      $sql.= ", pernottamento";
      $sql.= ", pernottamento * ( DATEDIFF(day, price_start, @data_partenza) ) as TotalCost";
      $sql.= " from roomprices";
      $sql.= " where idhotel=@idhotel and room=@room";
      $sql.= " and @data_partenza>=price_start and @data_partenza<=price_end and @data_arrivo<price_start";
     
      $sql.= " union ";

      $sql.= "select";
      $sql.= "  3 as tipo";
      $sql.= ", price_start";
      $sql.= ", price_end";
      $sql.= ", @data_arrivo as arrivo";
      $sql.= ", @data_partenza as partenza";
      $sql.= ", 1+DATEDIFF(day, price_start, price_end) as TotalDays";
      $sql.= ", pernottamento";
      $sql.= ", pernottamento * ( 1+DATEDIFF(day, price_start, price_end) ) as TotalCost";
      $sql.= " from roomprices";
      $sql.= " where idhotel=@idhotel and room=@room";
      $sql.= " and price_start>@data_arrivo and price_end<@data_partenza";
      $sql.= ") A";

      return str_replace("pernottamento", $IDprezzo, $sql);
    }
    ?>


eventualmente non mi suggeriresti un altro metodo di connessione? credo che il problema stia li perche' lo script di elaborazione dovrebbe essere ok

grazie della pazienza

ciao
 
esegui i due comandi che seguono, nella sequenza

DROP TABLE `roomprices`

CREATE TABLE IF NOT EXISTS `roomprices` ( ......

e inserisci nuovamente i record dei prezzi

riprova il tutto e ... fatti vivo, ma per favore se ci sono ancora errori, posta il log di php

dovrebbe darti ancora errore perché datediff è differente in mysql

grazie, ciao
Marino
 
Ultima modifica:
modifica tutte le datediff togliendo "day, ", per esempio

DATEDIFF(day, @data_arrivo, @data_partenza)";

diventa

DATEDIFF(@data_arrivo, @data_partenza)";

puoi anche provare la query in myphpadmin per verificare che non ci siano errori

fatti vivo
ciao
Marino
 
ciao,
nello zip allegato, ci sono 2 versioni (file 2 e file 3), con formule modificate per mysql,
prova prima con file 2 che dovrebbe essere quello corretto se ho letto bene il manuale mysql
fatti vivo
ciao
Marino
 

Allegati

niente da fare :(
con entrambi i file nello zip mi da sempre quell'errore ti posto i codici
Codice:
<?php

# http://localhost/test_site/php/test/FormazionePrezzo_2_MySql_MAXmin.php

require 'Config_DB.php';

$idhotel = 1;
$room    = 1;
$DataArrivo  = '2014/04/04';
$DataPartenza= '2014/04/11';
$IDprezzo    = 'pernottamento';       // nome della colonna da cercare per tipologia di pensione

$sql = PreparaSql($idhotel, $room, $DataArrivo, $DataPartenza, $IDprezzo);

$data = $db->Query_select($sql);
$dbresult = count($data);
if ($dbresult) {
  $TotalDays = $data[0][0];
  $TotalCost = $data[0][1];
  print "Hotel     : " . $idhotel      . "<br /> 
         Camera    : " . $room         . "<br />
         Pensione  : " . $IDprezzo     . "<br />
         Arrivo    : " . $DataArrivo   . "<br />
         Partenza  : " . $DataPartenza . "<br />
         TotalDays : " . $TotalDays    . "<br /> 
         TotalCost : " . $TotalCost    . "<br />";
}

function PreparaSql($idhotel='', $room='', $DataArrivo='', $DataPartenza='', $IDprezzo='') {

  // inserire eventuali controlli sui parametri

  $sql = "declare @idhotel as int;";
  $sql.= "declare @room    as int;";
  $sql.= "declare @data_arrivo   as datetime;";
  $sql.= "declare @data_partenza as datetime;";

  $sql.= "set @idhotel = " . $idhotel . ";";
  $sql.= "set @room    = " . $room    . ";";
  $sql.= "set @data_arrivo   = '" . $DataArrivo   . "';";
  $sql.= "set @data_partenza = '" . $DataPartenza . "';";

  $sql.= "select sum(A.TotalDays) as TotalDays, sum(A.TotalCost) as TotalCost from (";
  $sql.= "select";
  $sql.= "  1 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", CASE WHEN @data_partenza <= price_end";
  $sql.= "    THEN DATEDIFF(@data_partenza, @data_arrivo)";
  $sql.= "    ELSE DATEDIFF(price_end, @data_arrivo) + 1";
  $sql.= "  END as TotalDays";
  $sql.= ", pernottamento";
  $sql.= ", pernottamento * (";
  $sql.= "    CASE WHEN @data_partenza <= price_end";
  $sql.= "    THEN DATEDIFF(@data_partenza, @data_arrivo)";
  $sql.= "    ELSE DATEDIFF(price_end, @data_arrivo) + 1";
  $sql.= "    END ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and @data_arrivo>=price_start and @data_arrivo<=price_end";

  $sql.= " union ";

  $sql.= "select";
  $sql.= "  2 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", DATEDIFF(@data_partenza, price_start) as TotalDays";
  $sql.= ", pernottamento";
  $sql.= ", pernottamento * ( DATEDIFF(@data_partenza, price_start) ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and @data_partenza>=price_start and @data_partenza<=price_end and @data_arrivo<price_start";
 
  $sql.= " union ";

  $sql.= "select";
  $sql.= "  3 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", 1+DATEDIFF(price_end, price_start) as TotalDays";
  $sql.= ", pernottamento";
  $sql.= ", pernottamento * ( 1+DATEDIFF(price_end, price_start) ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and price_start>@data_arrivo and price_end<@data_partenza";
  $sql.= ") A";

  return str_replace("pernottamento", $IDprezzo, $sql);
}
?>

Codice:
<?php

# http://localhost/test_site/php/test/FormazionePrezzo_3_MySql_minMAX.php

require 'Config_DB.php';

$idhotel = 1;
$room    = 1;
$DataArrivo  = '2014/04/04';
$DataPartenza= '2014/04/11';
$IDprezzo    = 'pernottamento';       // nome della colonna da cercare per tipologia di pensione

$sql = PreparaSql($idhotel, $room, $DataArrivo, $DataPartenza, $IDprezzo);

$data = $db->Query_select($sql);
$dbresult = count($data);
if ($dbresult) {
  $TotalDays = $data[0][0];
  $TotalCost = $data[0][1];
  print "Hotel     : " . $idhotel      . "<br /> 
         Camera    : " . $room         . "<br />
         Pensione  : " . $IDprezzo     . "<br />
         Arrivo    : " . $DataArrivo   . "<br />
         Partenza  : " . $DataPartenza . "<br />
         TotalDays : " . $TotalDays    . "<br /> 
         TotalCost : " . $TotalCost    . "<br />";
}

function PreparaSql($idhotel='', $room='', $DataArrivo='', $DataPartenza='', $IDprezzo='') {

  // inserire eventuali controlli sui parametri

  $sql = "declare @idhotel as int;";
  $sql.= "declare @room    as int;";
  $sql.= "declare @data_arrivo   as datetime;";
  $sql.= "declare @data_partenza as datetime;";

  $sql.= "set @idhotel = " . $idhotel . ";";
  $sql.= "set @room    = " . $room    . ";";
  $sql.= "set @data_arrivo   = '" . $DataArrivo   . "';";
  $sql.= "set @data_partenza = '" . $DataPartenza . "';";

  $sql.= "select sum(A.TotalDays) as TotalDays, sum(A.TotalCost) as TotalCost from (";
  $sql.= "select";
  $sql.= "  1 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", CASE WHEN @data_partenza <= price_end";
  $sql.= "    THEN DATEDIFF(@data_arrivo, @data_partenza)";
  $sql.= "    ELSE DATEDIFF(@data_arrivo, price_end) + 1";
  $sql.= "  END as TotalDays";
  $sql.= ", pernottamento";
  $sql.= ", pernottamento * (";
  $sql.= "    CASE WHEN @data_partenza <= price_end";
  $sql.= "      THEN DATEDIFF(@data_arrivo, @data_partenza)";
  $sql.= "      ELSE DATEDIFF(@data_arrivo, price_end) + 1";
  $sql.= "    END ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and @data_arrivo>=price_start and @data_arrivo<=price_end";

  $sql.= " union ";

  $sql.= "select";
  $sql.= "  2 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", DATEDIFF(price_start, @data_partenza) as TotalDays";
  $sql.= ", pernottamento";
  $sql.= ", pernottamento * ( DATEDIFF(price_start, @data_partenza) ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and @data_partenza>=price_start and @data_partenza<=price_end and @data_arrivo<price_start";
 
  $sql.= " union ";

  $sql.= "select";
  $sql.= "  3 as tipo";
  $sql.= ", price_start";
  $sql.= ", price_end";
  $sql.= ", @data_arrivo as arrivo";
  $sql.= ", @data_partenza as partenza";
  $sql.= ", 1+DATEDIFF(price_start, price_end) as TotalDays";
  $sql.= ", pernottamento";
  $sql.= ", pernottamento * ( 1+DATEDIFF(price_start, price_end) ) as TotalCost";
  $sql.= " from roomprices";
  $sql.= " where idhotel=@idhotel and room=@room";
  $sql.= " and price_start>@data_arrivo and price_end<@data_partenza";
  $sql.= ") A";

  return str_replace("pernottamento", $IDprezzo, $sql);
}
?>
 
è inutile che posti il codice, mi aiuti solo se posti l'errore,

se non sai dove leggere il log di php,
per favore modifica la seguente funzione che si trova in 'Config_DB.php'
PHP:
  function handle_sql_errors($sql, $e){
    var_dump($sql); print "<br /><br />";
    var_dump($e->getCode()); print "<br /><br />";
    var_dump($e->getMessage()); print "<br /><br />";
    print "ERRORE INATTESO, contatta l'amministratore del sistema";
    die;
sostituisci solo le righe comprese tra "function" e "die"
riesegui il codice del file 2 e posta l'errore (tutto) che ti viene segnalato

grazie
ciao
Marino
 
Codice:
string(13) "PDO : OPEN DB"

int(2002)

string(105) "SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)"

ERRORE INATTESO, contatta l'amministratore del sistema

Dati mysql verificati e corretti - host aruba -
 
[QUOTEDati mysql verificati e corretti - host aruba -[/QUOTE]

quindi gli script li hai trasferiti nel tuo spazio su aruba e li esegui da li o per caso li esegui in locale sul tuo pc mettendo come host l'indirizzo ip di aruba ?
 

Discussioni simili