Autor Zpráva
4ever
Profil
Začínám s objektovým programováním a je tu něco co nechápu. Snad někdo vysvětlí...

1. Toto funguje zprávě (volání metody zvnitřku třídy)

class MY_formValidation {
  var $_save_errors = array();

	 function get_errors()
	{
		return $this->_error_array;
	}

	function run()
	{
		if ($total_errors > 0)
		{
		$pom = MY_formValidation::get_errors();
		print_r($this->_error_array);
		}
	}
}


Funguje (Vypíše mi seznam chyb).
Obdobně volání
$pom = $this->get_errors();
taky funguje.

2. to jsem nejdříve nechápal, ale pak jsem si vzpoměl, že všude se vnitřku třídy přistupuje pomocí $this ne takto:

Když ale místo
MY_formValidation::get_errors();
použiju
get_errors();
tak to vrací hlášku.
Fatal error: Call to undefined function get_errors() in P:\server\ci\application\libraries\MY_formValidation.php on line 340

Co to znamená, respektive, jak je to možný?
Ještě jsem zkoušel deklarovat public function get_errors() a taky to nejde volat normálně.

3. Nicméně můj hlavní problém spočívá v něčem jiném. Snažím se totiž zpřístupnit to pole s chybami mimo objekt. Takže mám takovouto definici:

public function &get_errors() { return $this->_save_errors; }

No a tu volám mimo třídu takto:
$MY =& my_formvalidation::get_errors();

No a nemůžu se dovolat:
Fatal error: Using $this when not in object context in P:\server\ci\application\libraries\MY_formValidation.php on line 268

Můžete mi poradit jak zpřístupnit tu třídu zvnějšku?
Kcko
Profil
$myValidation = new MY_formValidation;
print_r($myValidation ->get_errors());
Jozin
Profil
Zdravím,

1. jakou verzi PHP používáš, pokud 5+, tak používáš zastaralý zápis tříd. (přidání protected, private, public apod.)
a v metodách používáš proměnnou $_error_array, kterou nahoře nemáš deklarovanou. Je to tak správně?

2. Funkce není deklarovaná, protože je součástí třídy a tak lze volat jen z té třídy.

3. zpřístupnit to pole přece můžeš jen uvnitř třídy, nebo funkce musí volat tu třídu. Přidáním této metody do třídy to bude fungovat:
<?php
public function getAllErrors()
{
  return $this->_save_errors;
}
//a volání
$a = new MY_formValidation();
$a->getAllErrors();


Za případné chyby v kódu se omlouvám, Jozin.
4ever
Profil
1. jakou verzi PHP používáš, pokud 5+, tak používáš zastaralý zápis tříd. (přidání protected, private, public apod.)

používám php 5+ (Wampserver 1.7), teď nevím kde jsou ty čísla uvedené

a v metodách používáš proměnnou $_error_array, kterou nahoře nemáš deklarovanou. Je to tak správně?
To je omyl. Dal jsem tam omylem jinou proměnnou, ale var $_error_array = array (); mám deklarováno. Trochu jsem to zkrátil a udělal chybu při kopírování.

Já to zkusím a kdybych se ztrácel napíšu. Zatím díky
4ever
Profil
Mimochodem, tam už uvnitř jedna instance je:

class MY_formValidation {

	var $CI;
	public function __construct($rules = array())
	{
		$this->CI =& get_instance(); // ZKRÁCENO
	}
 // ZKRÁCENO	
}


Ale je to složitější. Tady ta funkce get_instance je definovaná ve třídě
class CI_Controller {
	private static $instance;
	public function __construct() {
		self::$instance =& $this;
	}

	public static function &get_instance(){ 
		return self::$instance;
	}	
	


Nechci aby to vypadalo moc složitě... Jen že tam už jedna instance CI existuje, ve které jsem však nenašel to pole s chybama. Snažím se upravit jednu třídu ke svému obrazu, ale zasekl jsem se na výpisu chyb.

PS: Moje funkce z prvního příkladu není odkazována pomocí &, ale to tam doplním později.
Jozin
Profil
Můžeš sem dát celou tu třídu, jak je a seznam změn, které chceš udělat?
4ever
Profil
Soubory a seznam provedených změn vůči originální knihovně

Jedná se původně o soubor s funkcema /system/helpers/form_helper.php
a třídu pro validaci dat z formuláře /system/libraries/Form_validation.php
z frameworku CodeIgniter. Změny, které jsem provedl jsou tyto:

Změnil jsem názvy pomocných funkcí pro formuláře místo form_input(), form_button(), form_button() atd. je jen input(),button(),submit(),hidden(),textarea(),radio(),checkbox(),select, atd...

Ve formvalidation.php jsem přidal možnost použít jiný formát pro konfiguraci pole, (line 118)
$this->_field_data[$field] = array(
			'field'				=> $field,
			'label'				=> $label,
			'rules'				=> $rules,
			'0'				    => $field,
			'1'				    => $label,
			'2'				    => $rules,

Přibyly tady ty indexy 0-2...

V celém souboru jsem zaměnil $row['field'] za $row['0'], $row['label'] za $row['1'] a $row['rules'] za $row['2']

dále napíšu jak se to používá
4ever
Profil
Takže my_form_helper.php slouží ke zjednodušenému zápisu prvků.

V CoderIgniteru se používá tvorba prvků dvěma způsoby:
     $this->load->library("form_validation");
     $this->form_validation->set_rules("name", "Name", "trim|required");
     $this->form_validation->set_rules("surname", "SurName", "trim|required");
     $this->form_validation->set_rules("email","Email address", "trim|required|valid_email");
     $this->form_validation->set_rules("username", "User Name", "trim|required|min_length[2]|max_length[20]");
     $this->form_validation->set_rules("psw", "Password", "trim|required|min_length[4]|max_length[32]");
     // special rule: matches[password]
     $this->form_validation->set_rules("psw2", "Password Confirmation", "trim|required|min_length[4]|max_length[32]|matches[psw]");
     $data['main_content_page'] = 'includes/forms/signup_form';
  if ($this->form_validation->run() == false ) die(validation_errors('<p class="error">')."</p>");


Nebo pomocí pole, což je ale dost zdlouhavé:
$config = array(
               array(
                     'field'   => 'username',
                     'label'   => 'Username',
                     'rules'   => 'required'
                  ),
               array(
                     'field'   => 'password',
                     'label'   => 'Password',
                     'rules'   => 'required'
                  ),
               array(
                     'field'   => 'passconf',
                     'label'   => 'Password Confirmation',
                     'rules'   => 'required'
                  ),   
               array(
                     'field'   => 'email',
                     'label'   => 'Email',
                     'rules'   => 'required'
                  )
            );


No a já jsem přišel na nápad zapsat to jednodušeji:
$config = array(
               array( 'username', 'Username', 'trim|required' ),
               array( 'password', 'Password', 'required' ),
               array( 'passconf', 'Password Confirmation', 'required|match[password]'),   
               array( 'email', 'Email','trim|required')
            );  


Takže toto je konfigurační pole, podle kterého si ta třída vytvoří jednotlivé prvky.

Dejme tomu, že už jsem provedl kontrolu odeslaných dat a nevyplnil jsem hesla. Tak teď jen chci zobrazit pole s chybama:

  if ($this->my_formvalidation->run() == false ) die(validation_errors('<p class="error">')."</p>");


Spouští se run() a výsledek je false. Spouští se validation_errors(); a to má vrátit ty hlášky.

MY_form_helper - validation_errors():
if ( ! function_exists('validation_errors'))
{                               
	function validation_errors($prefix = '', $suffix = '')
	{
		if (FALSE === ($OBJ =& _get_validation_object()))
		{
			return '';
		}

		return $OBJ->error_string($prefix, $suffix);
	}	    
}


odkazuje na & _get_validation_object() , Line 853

line 987
if ( ! function_exists('_get_validation_object'))
{
	function &_get_validation_object()
	{
		$CI =& get_instance();

		// We set this as a variable since we're returning by reference
		$return = FALSE;
	
//	..... shorted  ... 

/*		if ( ! isset($CI->load->_ci_classes) OR  
     ! isset($CI->load->library['validation']))   // default
    		{
			return $return;
		}

		 $object = $CI->load->_ci_classes['validation']; // default
*/		 		
    
		if ( ! isset($CI->$object) OR ! is_object($CI->$object))
		{
			return $return;
		}

		return $CI->$object;
	}
}
4ever
Profil
Jo a je třeba načíst ty dva soubory což se dělá v CodeIgniteru takto:
$this->load->library("MY_formValidation"); // my library v application\libraries
$this->load->helper("MY_form"); // my helper v application\helpers
4ever
Profil
Zabalil jsem celou aplikaci do jednoho souboru, takže kdyby se na to chtěl někdo podívat. Asi si s tím neporadím. Zvlášť jestli někdo používá CodeIgnitor. Ta třída není těžká, je jen dostat z ní to pole s uloženými chybami do obyčejné funkce, která leží někde v globálním prostředí.

Soubory dotyčné:
ci\application\helpers\MY_form_helper.php
ci\application\libraries\MY_formValidation.php
spouští se to přes
http://localhost/ci/index.php/login/create_member
a modul ci\application\models\auth_model.php

Na zbytek mých souborů se nedívejte jsou tam různé pokusy...

Funguje totakhle:
run(); // pokud $_POST obsahuje data a nastavili jste pravidla pro kontrolu vytvoří se seznam chyb
echo validation_errors(); // MY_form_helper.php
     // funkce provádí $OBJ =& _get_validation_object())
     ---> function & _get_validation_object(){
     následují moje pokusy
     	{
		$CI =& get_instance(); // NAČTENÍ INSTANCE CELÉHO CODEIGNITERU

		// We set this as a variable since we're returning by reference
		$return = FALSE;

      $CI->load->library('MY_FormValidation');     // LOAD MY LIBRARY
      $object = 'my_formvalidation'; // CONFUSING VARIABLE NAME
      ...
      return $CI->$object;		
     }
     
Jozin
Profil
Mrknu na to večer, je to trochu rozsáhlejší :)
4ever
Profil
POčkej, už jsem udělal nějaké změny

Ptal jsem se na foru CI ale tam mi nikdo nepomohl.

Tady si můžeš stáhnout aktuální verzi:

http://www.4shared.com/file/o1jhTSrc/ci_online.html

Hlavní objekt jsem už vrátil.

Dát dva řádky:
$CI->load->library('MY_FormValidation');    
$object = 'my_formvalidation';


Trapné je to, že celý zmatek byl kvůli nevhodnému pojmenování proměnné $object, místo $object_name. Ale i tak zůstává nedořešeno jak vlastně vrátit pole s chybami, protože to se neukládá. Funkce run() ve třídě, když ji spustíš, chyby ukáže. Ale funkce validation_errors ani validation_errors>>>&_get_validation_object nevrací pole. Prostě asi není uložené.

Řádek 1020 je zápis z testu originálního souboru (CI) form_helper:
print_r($CI->form_validation->_error_array);
Array
(
[psw] => The Password field is required.
[psw2] => The Password Confirmation field is required.
)

V mém MY_form_helper ale pole nevrátíš...

Jinak pro vytvoření formuláře teď požívám názvy funkcí takto: openform, input, password, select, button, submit, closeform...
4ever
Profil
No nevím, jestli ses na to díval, ale já jsem zatím došel k tomu, že v té třídě je taková velká funkce _execute(), která se spouští skrze run(); a aplikuje se na každý prvek ve formuláři. _execute obsahuje tento řádek dvakrát:

$this->_error_array[$row['field']] = $message;


Který ukládá chyby do toho pole. Nejdříve se má spustit run() a pak echo validate_errors(); zobrazí chyby. Tak to funguje v originální knihovně, ale když ji zkopíruju a přesunu jako MY_form_validation tak pak už to funguje jinak. Dochází k tomu, že poté co spustím run() tak se pole zase vynuluje, protože není nikde v hlavním objektu $CI. Nevím proč to tak je ale zatím mě napadá jediné řešení neuložit to jen do objektu ale taky do nějaké globální proměnné navíc. Tím to bude přístupné pro validate_errors(); každopádně něco je špatně..

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0