I have a problem with overrided functions of Yii. I am trying to override findByAttributes functions in Yii, but it returns this error:
PHP Fatal error: Class declarations may not be nested in /var/www/html/yii14/framework/collections/CListIterator.php on line 20
My codes of overrided function is like as following:
private function findByAttributes($attributes, $condition='', $params=array())
{
foreach($attributes as $attribute=>$value)
{
if($attribute === 'user_email') {
$attributes[$attribute] = md5('üyegirişyaptı'.$value);
}
}
return parent::findByAttributes($attributes, $condition, $params);
}
What is wrong in here?
I don't think the error is in the piece of code you provided.
Questions:
should findByAttributes be private ?
do you have a stacktrace for us ?
On a sidenote: I don't think you have to loop the array
if(array_key_exists('user_email', $attributes))
{
$attributes['user_email'] = md5('üyegirişyaptı'.$value);
}
Related
I am calling function form library in codeigniter and it's giving me below error
PHP Fatal error: Cannot access property started with '\0' in /system/core/Exceptions.php on line 85
Code:
$this->load->library('test_library');
TEST_LIBRARY::first();
Class file:
class TEST_LIBRARY
{
public function first(){
return "here";
}
}
However, when I call the function using this method $this->test_library->first(); it's working fine.
It was working both ways before not sure what's going on. There is no other log messages in error.log file. How can I debug further and fix this issue?
Function first is not static but you called as if it is. Change test_libaray.php to :
class TEST_LIBRARY {
public function __construct() {}
public function first() {
return "here"; // i suggest to use __METHOD__ or __LINE__ instead
}
}
And then try:
$test_library = new TEST_LIBRARY();
$test_libaray->first();
instead of:
TEST_LIBRARY::first();
Or you can just change first static.
I have somme issue in PHP, I put this code in my index.php :
$test = $wke ->sql
->insert("test")
->values(array("foo" => "bar"))
->go();
This code worked fine but when I use this code in an method (debug.class.php) like this :
$test = sql::insert("test")
->values(array("foo" => "bar"))
->go();
It doesn't work :
Fatal error: Call to undefined method template::values() [...]
My "insert" (and "values") method is in my SQL class, not my template class. I know that my second exemple is called in my template class but at in the end, I call sql::insert, not self::insert or template::insert. This is why I'm lost.
Sorry for my English ! Thank you in advance.
PS : This is my sql::insert method
static $queryBuffer;
public function insert($in) {
self::$queryBuffer->type = "insert";
self::$queryBuffer->data->insert = $in;
return $this;
}
Change your insert function as follows.
static $queryBuffer;
public static function insert($in) {
self::$queryBuffer->type = "insert";
self::$queryBuffer->data->insert = $in;
return $this;
}
The insert should be static to call with the class name without the object.
i keep on having this error message on Kohana 3
ErrorException [ Warning ]: call_user_func() expects parameter 1 to be a valid callback, function 'pages_save' not found or invalid function name
inside my controller i have the following codes:
public function action_pages(){
return call_user_func('pages_'.$this->request->param('id'));
}
function pages_save(){
$this->auto_render = false;
}
if i would access admin/pages/save i should be redirected to pages_save() function right? but somehow i cant? Kohana keeps on throwing me the following exception stated above. how should i go with this. optimizing is one thing in my mind, if i do switch-case / if-else block it would take me forever if there are too many that i need to do...
First of all you should trust the error message. Which means you did an error. Clean up your code a little:
public function action_pages()
{
$method = sprintf('pages_%s', $this->request->param('id'));
return call_user_func($method);
}
public function pages_save()
{
$this->auto_render = false;
}
The changes here are only little: Added the missing visibility specifier to pages_save and put the methodname into a variable called $method.
Now it's getting more visible, that you used a public function name here which is not defined, instead of the class method you'd like to invoke on $this. So let's fix that:
public function action_pages()
{
$method = sprintf('pages_%s', $this->request->param('id'));
return $this->$method();
}
This should solve your issue.
It's not Kohana, it's PHP that is throwing the error. To use call_user_func() from within a class, you need to use the following syntax:
call_user_func(array($this, 'pages_'.$this->request->param('id')));
I'm running PHP 5.3.6 with MAMP 2.0.1 on Mac OS X Lion and I'm using Kohana 3.1.3.1.
I try to override the __set() and __get() methods of the standard Kohana ORM module with my own methods. Some of my models extend my class which extends the ORM class.
<?php
class ORM_Localization extends ORM
{
protected static $_language_cache = array();
protected $_languages = array();
public function __construct($id = NULL)
{
parent::__construct($id);
// Load languages which are accepted by the client
$this->_languages = array_keys(Application::languages());
}
public function __get($name)
{
/* Debugging #1 */ echo 'GET'.$name;
/* Debugging #2 */ // exit;
return $this->localization($name);
}
public function __set($name, $value)
{
/* Debugging #3 */ var_dump($this->_table_columns);
/* Debugging #4 */ echo 'SET::'.$name;
/* Debugging #5 */ // exit;
$this->localization($name, $value);
}
public function localization($name, $value = NULL)
{
if (!array_key_exists($name, $this->_table_columns)) {
// Load avaiable languages from database if not already done
if (empty(ORM_Localization::$_language_cache)) {
ORM_Localization::$_language_cache = ORM::factory('languages')
->find_all()
->as_array('id', 'identifier');
}
$languages = array();
// Find the IDs of the languages from the database which match the given language
foreach ($this->languages as $language) {
$parts = explode('-', $language);
do {
$identifier = implode('-', $parts);
if ($id = array_search($identifier, ORM_Localization::$_language_cache)) {
$languages[] = $id;
}
array_pop($parts);
} while($parts);
}
// Find localization
foreach ($languages as $language) {
$localization = $this->localizations->where('language_id', '=', $language)->find();
try {
if ($value === NULL) {
return $localization->$name;
} else {
$localization->$name = $value;
}
} catch (Kohana_Exception $exception) {}
}
}
if ($value === NULL) {
return parent::__get($name);
} else {
parent::__set($name, $value);
}
}
}
But in PHP 5.3.6, I get the following error message:
Exception [ 0 ]: Could not execute Model_Hotel::__construct()
Model_Hotel extends this class and does not have an own construct.
This is the code of Model_Hotel, a standard Kohana ORM model: http://pastie.org/private/vuyig90phwqr9f34crwg
With PHP 5.2.17, I get another one:
ErrorException [ Warning ]: array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object
In Kohana, my model which extends my class is called by mysql_fetch_object(), somewhere deep in the orm modules code.
However, if I echo the called property in __set() and exit (#4 and #5) afterwards, it outputs "SET::id" and doesn't show the error message.
If I var_dump() $this->_table_columns (or any other property of this class, #3), I get "NULL" which is the value that this property has before it's initialized.
If I repeat the same with $this->_languages, I get an empty array which should be filled with several languages. It's like the class was never initialized with the __construct. This explains the error which I get in PHP 5.2.17, because $this->_table_columns is NULL and not an array.
I can uncomment my __construct and I still get the same error, the fault has to be in my localization() method.
I searched for several days now and I have absolutely no idea what could be wrong.
ORM::__set() is expected to load cast data from mysql_fetch_object() call. You must allow it to set casted value for this cause:
public function __set($column, $value)
{
if ( ! isset($this->_object_name))
{
// Object not yet constructed, so we're loading data from a database call cast
$this->_cast_data[$column] = $value;
}
else
{
// Set the model's column to given value
$this->localization($column, $value);
}
}
Altough I don't like this solution either, you should be overriding ORM::set() instead.
__construct() is called automatically after initialization of an object.
$class = new Object;
I have a bit more information on this question, as I ran into the same problem.
1) I found a PHP bug report that documents that in mysqli and mysql_fetch_object __set() is called before __construct(). The report is from 2009 and supposedly was fixed, but in the version of 5.3 I'm running it still seems to happen. Here it is: https://bugs.php.net/bug.php?id=48487
2) If, in the process of executing your __set() method you throw an exception or some other error occurs you'll get this vague "can't call X::__construct()" message instead of the real exception/error message.
I could resolve my problem thusly:
public function __set($key, $val){
if($constructor_has_not_run){
$this->__construct();
}
//do stuff
}
I'm a bit lucky in my case because I can let the constructor run twice without any problems, but you might not be in the same boat.
all my websites share a common starter, that deals with urls, file locations, etc.. There are 3 cases that need to be handled - is directory, file exists and file does not exist. Each application has unique code for each case. I decided to tinker with runkit a bit and I am trying to unify the code. Each case will be handled by a function, that could be redefined via runkit.
Consider this code:
class start {
function __construct() {
$this->options = array();
}
public function process() {
// some code here
$this->file_not_exists();
}
public function file_not_exists() {
$this->options['page'] = 222;
}
public function redefine($what, $code) {
runkit_method_redefine(get_class($this), $what, '', $code, RUNKIT_ACC_PUBLIC);
}
}
$start = new start();
$start->redefine('file_not_exists', '$this->options["page"] = 333;')
// page is now 333
This part works as intended. But when I try to change the code so the redefined method calls user function it works. But, for the love of god, I cant figure out how to pass the $this to the function.
Redefine method looks like this:
public function redefine($what, $code) {
runkit_method_redefine(get_class($this), $what, '', 'call_user_func('.$code.'(), '.$this.');', RUNKIT_ACC_PUBLIC)
}
This doesn't work, no matter what I try (call_user_func_array as well). I just cant figure it out. For the record:
public function redefine($what, $code) {
my_user_function($this);
}
Does work.
Any help is appreciated.
Note that this is just an experiment and I would like to know how to do this :)
Edit:
I get:
Catchable fatal error: Object of class starter could not be converted to string in blablallala\rewrite_starter2.php on line 153
{... removed as not necessary ...}
==== EDIT =====
[For the new problem, what you need is this]
<?
class start {
function __construct() {
$this->options = array();
}
public function process() {
// some code here
$this->file_not_exists();
}
public function file_not_exists() {
$this->options['page'] = 222;
}
public function redefine($what, $code) {
runkit_method_redefine(get_class($this),
$what,
'',
'call_user_func(array($this,' .$code. '),$this);',
RUNKIT_ACC_PUBLIC);
}
public function my_func($someobj)
{
print_r($someobj);
}
}
$start = new start();
$start->redefine('file_not_exists', 'my_func');
$start->process();
?>
The documentation on the call_user_func function says that the first argument is 'callable'. So to call the class method dynamically, you should pass the array($obj, 'func_name').