Yes! That would be the best solution. But with this you are touching question (not answered, if I’m not mistaken) from some other thread about how to use own classes that extends core Yii classes? I.e. if they are not directly called within code, only executed by other Yii classes or methods? In other words - what should I do or write in my code to force Yii to use my own extension instead of original implementation of let’s say… CHttpRequest or CActiveRecord for example or any other class that isn’t called directly in the code?
You can find the basic core components of CWebApplication here. These components are defined by default, you don’t have to set them in config. BUT, you can set them in config and specify a different class.
So… If I get, what you mean… I should extend CDbConnection to my own class (for example MyDbConnection) altering its getSchema() method so it would call my own schema (for example MyOciSchema) for Oracle driver and then change components part of configuration, just the way you shown, to specify that db component should use MyDbConnection as class, instead of original one, right?
This way I can store both MyDbConnection and MyOciSchema along with my code and be able to use original CActiveRecord (and all other db classes that are using CDbConnection) but with my own schema, right?
Yes, but I just noticed $_schema is private property, so you can’t extend it. Maybe there’s some way by extending CActiveRecord. But it would be perfect if you could use your own schema class in CDbConnection
I must be missing something, because I don’t see any problem that $_schema is private, when using my approach.
Since I will not use any other DB than Oracle in this particular project, I’m thinking about extending CDbConnection to as simple class as possible, for example:
* MyDbConnection is the customized CDbConnection class, that forces all connections
* to Oracle db to use own class MyOciSchema instead of bulid-in COciSchema.
class MyDbConnection extends CDbConnection
public function getSchema()
if($this->_schema == NULL)
$driver = $this->getDriverName();
return $this->_schema = new MyOciSchema($this);
else throw new CDbException(Yii::t('yii', 'CDbConnection is inactive and cannot perform any DB operations.'));
else return $this->_schema;
and then, as you wrote, in the configuration:
But you seems to be concerned that this will not work?
Yes, you are right. But if I have to introduce some serious changes to COciSchema, then in my opinion it is always better to do this my way and only change one line in original source code of Yii - making $_schema protected instead of private. This way I’ll be able to use my own MyOciSchema instead of changing original one. Am I right?
There is also another option (as my friend told me). Property _$schema is only used in getSchema() and close(). So it is possible to introduce own variable, for example $myschema in extended class and use it instead of original, private one.
Than it is good idea to open bug tracker ticket asking for this, right?
If you set it to protected, you can’t extend from the original class (it’s not possible to change/override the “private” state). But yes you may introduce your own property and replace it in the related methods.
The reason for all those private properties in Yii is backward compatibility. For example, let’s assume it were protected already and in the next version we change the property name for some reason -> then your code would be broken since you still rely on the original property name. This is obviously bad for hacking. I found myself in need many times to have a protected property instead of private. Some of them changed to protected in the latest versions luckily (e.g. CClientScript::$metaTags). So I suggest to open up a ticket and then we see what happens.