| Autor | Zpráva | ||
|---|---|---|---|
| scorapka Profil |
#1 · Zasláno: 2. 11. 2013, 22:14:38 · Upravil/a: scorapka
Dobrý den,
koupil jsem si knihu Programujeme vlastní e-shop v PHP 5, Michael Peacock http://knihy.cpress.cz/programujeme-vlastni-e-shop.html Stáhl jsem si zdrojové kody příkladů. Vložil do svého adresáře www. Vytvořil databázi a udělal vše co je v souboru ČTIMNE.txt Po spuštění vyskakují chyby: Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Můžete také vyzkoušet ale prosím co znamená tato chyba? Děkuji. zkoušel jsem nastavit metodu na statickou (public static) ale nepomáha, dále to píše chybu: Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 129 tady je ta chybná funkce, co hlásí chybu, že není statická... public function buildFromTemplates()
{
$bits = func_get_args();
$content = "";
foreach( $bits as $bit )
{
if( strpos( $bit, 'views/' ) === false )
{
$bit = 'views/' . PHPEcommerceFrameworkRegistry::getSetting('view') . '/templates/' . $bit;
}
if( file_exists( $bit ) == true )
{
$content .= file_get_contents( $bit );
}
}
$this->page->setContent( $content );
} |
||
| scorapka Profil |
#2 · Zasláno: 3. 11. 2013, 10:22:24
tak díky za pomoc:(
|
||
| Tori Profil |
scorapka:
„zkoušel jsem nastavit metodu na statickou (public static) ale nepomáha, dále to píše chybu:“ To je ale jiná chyba z úplně jiné třídy, ne? Varianta 1: Jak vypadá ta metoda getSetting? Potřebuje / využívá na něco instanci Registry?
Varianta 2: jak vypadá třída Registry? Logicky bych podle názvu čekala, že to bude singleton, a tedy bude mít nějakou metodu Registry::getInstance() - má, nemá?
Kdyžtak se někdy k večeru kouknu na ty zdrojáky. |
||
| scorapka Profil |
#4 · Zasláno: 3. 11. 2013, 11:36:17 · Upravil/a: scorapka
Tori:
„zkoušel jsem nastavit metodu na statickou (public static) ale nepomáha, dále to píše chybu: To je ale jiná chyba z úplně jiné třídy, ne?“ ano další chyba to je úplně jiné třídy. Abych byl konkrétnější, hodím sem úplný výpis chyb: Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Notice: Uninitialized string offset: 36 in C:\www\ecom\models\basket\model.php on line 163 Notice: Undefined variable: weightFound in C:\www\ecom\models\basket\model.php on line 127 Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 129 Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 132 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 33 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\page.class.php on line 130 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 111 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 111 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 111 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\template.class.php on line 78 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\template.class.php on line 83 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 139 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 139 Varianta 1: /**
* Vrátí nastavení z registru
* @param String $key klíč použitý pro uložení nastavení
* @return String nastavení
*/
public function getSetting( $key )
{
return self::$settings[ $key ];
}Varianta 2: Třída registry má singleton /**
* metoda singleton pro přístup k objektu
* @access public
* @return
*/
public static function singleton()
{
if( !isset( self::$instance ) )
{
$obj = __CLASS__;
self::$instance = new $obj;
}
return self::$instance;
}Hodím ti sem celou třídu registry.class.php <?php
/**
* The PCARegistry object
* Implements the Registry and Singleton design patterns
* Building a PHP Ecommerce Framework
*
* @version 1.0
* @author Michael Peacock
*/
class PHPEcommerceFrameworkRegistry {
/**
* pole objektů uložených v registru
* @access private
*/
private static $objects = array();
/**
* pole nastavení uložených v registru
* @access private
*/
private static $settings = array();
/**
* instance registru
* @access private
*/
private static $instance;
private static $urlPath;
private static $urlBits = array();
/**
* Soukromý konstrutkor zabrání přímému vytvoření
* @access private
*/
private function __construct()
{
}
/**
* metoda singleton pro přístup k objektu
* @access public
* @return
*/
public static function singleton()
{
if( !isset( self::$instance ) )
{
$obj = __CLASS__;
self::$instance = new $obj;
}
return self::$instance;
}
/**
* zabrání kolonování objektu: vyvolá chybu E_USER_ERROR
*/
public function __clone()
{
trigger_error( 'Klonování registru není povoleno', E_USER_ERROR );
}
/**
* Uloží objekt do registru
* @param String $object název objektu
* @param String $key klíč do pole
* @return void
*/
public function storeObject( $object, $key )
{
if( strpos( $object, 'database' ) !== false )
{
$object_a = str_replace( '.database', 'database', $object);
$object = str_replace( '.database', '', $object);
require_once('databaseobjects/' . $object . '.database.class.php');
$object = $object_a;
}
else
{
require_once('objects/' . $object . '.class.php');
}
self::$objects[ $key ] = new $object( self::$instance );
}
/**
* Vrátí objekt z registru
* @param String $key klíč do pole použitý při uložení objektu
* @return object - objekt
*/
public function getObject( $key )
{
if( is_object ( self::$objects[ $key ] ) )
{
return self::$objects[ $key ];
}
}
/**
* Uloží nastavení do registru
* @param String $data the setting we wish to store
* @param String $key klíč pro přístup k nastavení
* @return void
*/
public function storeSetting( $data, $key )
{
self::$settings[ $key ] = $data;
}
/**
* Vrátí nastavení z registru
* @param String $key klíč použitý pro uložení nastavení
* @return String nastavení
*/
public function getSetting( $key )
{
return self::$settings[ $key ];
}
/**
* Vrátí data z aktuální adresy URL
* @return void
*/
public function getURLData()
{
$urldata = (isset($_GET['page'])) ? $_GET['page'] : '' ;
self::$urlPath = $urldata;
if( $urldata == '' )
{
self::$urlBits[] = 'home';
self::$urlPath = 'home';
}
else
{
$data = explode( '/', $urldata );
while ( !empty( $data ) && strlen( reset( $data ) ) === 0 )
{
array_shift( $data );
}
while ( !empty( $data ) && strlen( end( $data ) ) === 0)
{
array_pop($data);
}
self::$urlBits = $this->array_trim( $data );
}
}
public function redirectUser( $urlPath, $header, $message, $admin = false)
{
self::getObject('template')->buildFromTemplates('redirect.tpl.php');
self::getObject('template')->getPage()->addTag( 'header', $header );
self::getObject('template')->getPage()->addTag( 'message', $message );
if( $admin != true )
{
self::getObject('template')->getPage()->addTag('url', $urlPath );
}
else
{
//
}
}
public function getURLBits()
{
return self::$urlBits;
}
public function getURLBit( $whichBit )
{
return self::$urlBits[ $whichBit ];
}
public function getURLPath()
{
return self::$urlPath;
}
private function array_trim( $array )
{
while ( ! empty( $array ) && strlen( reset( $array ) ) === 0)
{
array_shift( $array );
}
while ( !empty( $array ) && strlen( end( $array ) ) === 0)
{
array_pop( $array );
}
return $array;
}
}
?> |
||
| Tori Profil |
Buď můžete všechna volání
PHPEcommerceFrameworkRegistry::getNěco() a PHPEcommerceFrameworkRegistry::storeNěco()
přepsat na PHPEcommerceFrameworkRegistry::singleton()->getNěco(), anebo metody getSettings, storeSettings, getObject a storeObject změnit na statické. První možnost je bez problémů použitelná hned. U té druhé by bylo potřeba nejdřív ověřit v celém kódu eshopu, jestli se ty metody někde nevolají i na instanci (např. nechat vyhledat řetězec "->getSettings").
Je to docela hloupé, že ke knížce jsou zdrojáky, které generují chyby. E_STRICT bych ještě přežila, to může být i rokem napsání anglické verze knihy, ale E_NOTICE by tam už být nemělo. pozn. ve [#3] jsem se ptala kvůli těmto dvěma možnostem, jen v opačném pořadí. |
||
| scorapka Profil |
#6 · Zasláno: 3. 11. 2013, 21:31:49
Tori:
tak jsem ve tříde template.class.php přpsal ty volání (přidal singleton()->) chyby to už nepíše. Super. Takže díky moc za pomoc. Ale ještě to hlásí tyhle chyby: Notice: Undefined variable: weightFound in C:\www\ecom\models\basket\model.php on line 127 Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 129 Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 132 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\page.class.php on line 130 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\template.class.php on line 78 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\template.class.php on line 83 Notice: Undefined variable: filterSQL in C:\www\ecom\controllers\products\controller.php on line 222 Notice: Uninitialized string offset: 36 in C:\www\ecom\models\basket\model.php on line 163 Co tam jsou zase za chyby? |
||
| Tori Profil |
Koukla jsem na to zběžně, bez phpdoc to teda není úplně intuitivní. V models\basket\model.php se na ř.90+100 provádí zřejmě tentýž SQL dotaz dvakrát, ale chybu to nezpůsobí.
- models\basket\model.php:127 - Jelikož se musí sčítat váha všech produktů, tak by asi na ř.126 mělo být $weightFound = false;.
- models\basket\model.php:129+132 - Tohle vypadá, že metoda getShippingWeightCosts vrací prázdné pole. Asi si musíte nejdřív někde v backoffice nastavit alespoň jeden typ poplatků podle váhy zásilky (např. minimálně 0 kg, poplatek 0 Kč.)
- registry\objects\page.class.php:130 - Zkontrolujte si, odkud se to volá, jaká šablona a jaký blok je z ní požadován, jestli není někde v šabloně překlep. Asi by to šlo vyřešit výchozí hodnotou, pokud tag není nalezen:
if (preg_match ('#<!-- START '. $tag . ' -->(.+?)<!-- END '. $tag . ' -->#si', $this->content, $tor) {
$tor = str_replace ('<!-- START '. $tag . ' -->', "", $tor[0]);
$tor = str_replace ('<!-- END ' . $tag . ' -->', "", $tor);
return $tor;
} else {
return '';
}return preg_match('#<!-- START '.$tag.' -->(.+?)<!-- END '.$tag.' -->#si', $this->content, $tor) ? $tor[1] : '';- registry\objects\template.class.php:78+83 - najděte si volání metod addTag a/nebo addPPTag (asi to bude zapsané jako PHPEcommerceFrameworkRegistry::singleton()->getObject('page')->addTag) a zkontrolujte, co se tam posílá za data. Jako druhý parametr by mělo jít nějaké pole, zřejmě není v očekávaném tvaru, chybné klíče jednotlivých prvků apod. Případně pokud je klíč $data[0] nepovinný, tak změňte podmínku na ř.75 na: if (is_array($data) && isset($data[0])) {
- controllers\products\controller.php:222 - to má být zřejmě $this->filterSQL. V kódech k angl.originálu je to taky blbě.
- models\basket\model.php:163 - změňte ten řádek na $string .= $characters[mt_rand(0, strlen($characters)-1 )]; - Autor zapomněl, že ofset posledního bajtu v řetězci je o 1 menší, než délka řetězce.
No, přeju hodně štěstí při dohledávání a opravách dalších chybek. Většina z toho jsou jen maličkosti (spoléhání na existenci indexu v poli apod.), ale některé jsou docela hloupé chyby. To je ale IMHO vina nakladatele, resp. odborného redaktora, který by ten kód měl nejen projít a zkontrolovat syntax+překlad, ale i spustit a vyzkoušet. |
||
| scorapka Profil |
#8 · Zasláno: 4. 11. 2013, 11:46:21
Tori:
Tak jsem to začal ladit. Ale přesně nechápu jak myslíš tohle: - models\basket\model.php:129+132 - Tohle vypadá, že metoda getShippingWeightCosts vrací prázdné pole. Asi si musíte nejdřív někde v backoffice nastavit alespoň jeden typ poplatků podle váhy zásilky (např. minimálně 0 kg, poplatek 0 Kč.) Jsem začátečník a neumím si představit jak se nastavuje v backofficu ty poplatky. Máš na mysli v phpmyadminu, a nastavit v databazi ecom? a toto: - controllers\products\controller.php:222 - to má být zřejmě $this->filterSQL. V kódech k angl.originálu je to taky blbě. máš na mysli nahradit if( $filterSQL == '' ) tímhle tím if( $this->filterSQL )
Jinak ti chci poděkovat za tvoji laskavost, že si mi pomohla opravit ty chybné kody. |
||
| Tori Profil |
Ad $filterSQL: ano, přesně tak,
if ($this->filterSQL == ''). Když si projdete tu třídu, tak někde se tam do proměnné $this->filterSQL nastavuje nějaké omezení, předpokládala jsem teda, že se to týká i této metody.
K příplatkům za váhu zásilky - mělo by se to nastavit někde v tom eshopu. Ale můžete i přímo přidat 1 řádek do databáze. Zkuste spustit v phpmyadmin tohle, snad by to mělo být správně. INSERT INTO `shipping_costs_weight` (`ID`, `shipping_id`, `lower_weight`, `cost`) VALUES (1, 1, 0.0, 0.0); |
||
| scorapka Profil |
#10 · Zasláno: 4. 11. 2013, 12:20:12
Tori:
Tak už se mi podařilo:) jak nahrát do databáze poplatky, tak i přidat if ($this->filterSQL == '') děkuji ti!
Jenže ta ukázka e-shopu má nekonečně mnoho chyb. Ještě to vypisuje tohle: Notice: Undefined variable: currentWeight in C:\www\ecom\models\basket\model.php on line 129 Notice: Undefined index: in C:\www\ecom\models\basket\model.php on line 129 Notice: Undefined variable: currentWeight in C:\www\ecom\models\basket\model.php on line 132 Notice: Undefined index: in C:\www\ecom\models\basket\model.php on line 132 Notice: Array to string conversion in C:\www\ecom\registry\objects\template.class.php on line 92 |
||
| Tori Profil |
#11 · Zasláno: 4. 11. 2013, 12:43:25
Ty první dvě chyby (
models\basket\model.php:129+132) by to vypisovat rozhodně nemělo. Nepřepsal jste si ten řádek, kde je definovaná výchozí hodnota 0? Měly by tam (po předchozí změně) být dva řádky: $currentWeight = 0; $weightFound = false; while( $weightFound == false ) ...
Tu druhou chybu jsem asi způsobila svou radou, nekoukla jsem se na druhou část podmínky. Asi teda bude lepší tohle: if( is_array( $data ) )
{
if( isset($data[0]) && $data[0] == 'SQL' )
{
// jedná se o výsledek dotazu uložený v mezipaměti, značky se nahradí tímto výsledkem
$this->replaceDBTags( $tag, $data[1] );
}
elseif( isset($data[0]) && $data[0] == 'DATA' )
{
// jedná se o data uložená v mezipaměti, značky se nahradí daty z mezipaměti
$this->replaceDataTags( $tag, $data[1] );
}
} |
||
| scorapka Profil |
#12 · Zasláno: 4. 11. 2013, 14:05:26
Tori:
tak to se omlouvám, zapomněl jsem tam přidat $currentWeight = 0;, to byla zase moje chyba:)
nicméně ještě jsou tam chyby: Warning: Illegal string offset 'weight' in C:\www\ecom\models\basket\model.php on line 130 Warning: Illegal string offset 'cost' in C:\www\ecom\models\basket\model.php on line 133 |
||
| Tori Profil |
#13 · Zasláno: 4. 11. 2013, 14:33:26
Tohle zvládnete opravit. ;)
„Illegal string offset 'weight'“ znamená, že se někdo pokouší použít klíč "weight" u proměnné, která není pole, ale řetězec. Takže se kouknete, že proměnná $shippingCosts je naplněná pomocí metody getShippingWeightCosts. V téhle metodě, která má vracet různé typy doplatků podle váhy zboží, se vytváří pole v jiném tvaru, než jaký je očekáván na ř.130. Máte teda dvě nesourodé varianty toho pole a musíte to sjednotit na jednu z nich. Dejte si vyhledat v celém eshopu, kde všude se volá metoda getShippingWeightCosts, koukněte se, jak se s tou návratovou hodnotou pracuje (tj. kterou z těch dvou možností, dvou způsobů uspořádání pole, očekává). Podle toho se pak rozhodněte:
A - metoda getShippingWeightCosts se buď jinde nepoužívá, anebo se tam taky počítá se stejnou strukturou pole, jako v místě, kde vám to hlásilo chyby. --> přepíšte metodu getShippingWeightCosts tak, aby vracela pole v jiném tvaru
B1 - na ostatních místech, kde se volá metoda getShippingWeightCosts, se pracuje s tou strukturou pole, kterou ona skutečně vrací. --> přepíšete tuhle část metody checkBasket, aby pracovala s jiným tvarem pole.
Ale tohle řešení by bylo dost obtížné, takže je možnost B2: --> přidáte další metodu, která použije stejný SQL dotaz jako getShippingWeightCosts, ale bude vracet pole v jiném tvaru.
|
||
| scorapka Profil |
#14 · Zasláno: 4. 11. 2013, 17:53:45 · Upravil/a: scorapka
Tori:
No já jsem fakt úplný začátečník, takže jsem hledal metodu getShippingWeightCosts v celém eshopu a nikde jinde není, jen v C:\www\ecom\models\basket\model.php na řádku 358
Nevím jak hledáte efektivněji ale já musel otevírat v PSPpadu každý soubor zvlášt a prohledávat zda tam není. Chci si zvolit způsob A přepsat metodu getShippingWeightCosts , tak aby vracela pole ve správném tvaru. ale fakt netuším jak to udělat:(že by to nemělo vracet Pole array()? Notice: Undefined property: Basket::$isChecked in C:\www\ecom\controllers\basket\controller.php on line 62 |
||
| scorapka Profil |
#15 · Zasláno: 5. 11. 2013, 11:26:08
Tori:
Tak jsem na to ještě nepřišel...jinak ti děkuji, že si mi pomáhala Tori. |
||
| Tori Profil |
V PSPadu nevím, používám NetBeans a tam se dá hledat ve vybraných adresářích.
K tomu poli: (všechno se týká jen \models\basket\model.php, a předpokládám, že v tabulce shipping_costs_weight jsou data: ID | shipping_id | lower_weight | cost | 1 | 1 | 0.0 | 0.0 | 2 | 1 | 15.0 | 20.0 | Podle toho, jak se na ř.129 pracuje s polem $weightCosts, by mělo mít strukturu
array( 0 => array( 'weight' => 15.0, 'cost' => 20.0, ), 1 => array( 'weight' => 0.0, 'cost' => 0.0, ), ) getShippingWeightCosts vrací pole ve tvaru:
array( 15.0 => 20.0, 0.0 => 0.0, ) getShippingWeightCosts takto:
$shipping_weights_sql = "SELECT cost, lower_weight FROM shipping_costs_weight WHERE shipping_id={$this->shippingMethodID} ORDER BY lower_weight DESC";
$this->registry->getObject('db')->executeQuery( $shipping_weights_sql );
$weights = array();
while( $data = $this->registry->getObject('db')->getRows() )
{
$weights[] = array('weight' => $data['lower_weight'], 'cost' => $data['cost']);
}
return $weights; // dopravné: dle váhy
// $currentWeight = 0; -- tohle není potřeba, smazat
// $weightFound = false; -- tohle taky
foreach ($weightCosts as $weight => $cost)
{
if( $contents['product_weight'] >= $weight )
{
$this->shippingCost = $this->shippingCost + ( $cost * $contents['product_quantity'] );
break;
}
} |
||
| scorapka Profil |
#17 · Zasláno: 5. 11. 2013, 18:16:30
Tori:
ahaaaaa, už to chápu Super, už to funguje, děkuji:) ale ted se snažím odstranit poslední chybu, se kterou si opět nevím rady:( chyba se vypíše při přidání produktu do košíku, a jak je vidět, košík nefunguje jak má... Notice: Undefined property: Basket::$isChecked in C:\www\ecom\controllers\basket\controller.php on line 62
|
||
| Tori Profil |
Koukněte do toho modelu, ona se totiž ta proměnná jmenuje trochu jinak.
↓A jo, díky za opravu, ona je to vlastně soukromá vlastnost. |
||
| Rfilip Profil |
62, 130 a 156 řádek souboru C:\www\ecom\controllers\basket\controller.php má být:
if( ! $this->basket->isChecked() == true ) { $this->basket->checkBasket(); } |
||
| scorapka Profil |
#20 · Zasláno: 5. 11. 2013, 19:59:49
Tak Vám oběma děkuji:) chyba ischecked je vyresena...
ale stejně nejde přidat více jak jedna položka do košíku...což je divné... teď se snad bude s tím kodem pomocí knihy lépe pracovat, když to ted "zatím" nehlásí zadné chyby. |
||
|
Časová prodleva: 12 let
|
|||
0