I have a class that defines new meta boxes in an admin area of a web site. Each new box requires quite a lot of arguments, so the defining of each new object is kept in a separate function.
function my_metabox(){
$args = array(/*the args*/);
$metabox = new MetaBox($args);
}
And then I have a function, positioned where I need the boxes loaded, to load all of the metaboxes at once.
function load_metaboxes(){
my_metabox();
my_other_boxes();
etc_etc();
}
The problem mostly is having to manually alert the load_metaboxes() function whenever I create a new box, is there a better way to structure this?
Maybe you can use something like this:
//declaring my functions
function test_funct_1() { echo 'test'; return true; }
function test_funct_2() { return true; }
function test_funct_3() { return true; }
function test_funct_4() { return true; }
//get all function declared
$func = get_defined_functions();
//show only functions declared by user (you)
print_r($func['user']);
//call a individual function
$func['user'][0]();
use php autload magin method
here is the documentation
http://php.net/manual/en/language.oop5.autoload.php
in your class create a method name __autoload and call all the function in it so when you make an instance of the class the function called in __autoload will automatically loaded
Related
I have a called class called ClientPolicy which is like this
class ClientPolicy {
var $serverHost="www.example.com";
var $httpPort = 80;
var $httpsPort = 443;
var $appKey;
var $secKey;
var $defaultContentCharset = "UTF-8";
}
and another class file name SyncAPIClient which looks like this
class SyncAPIClient{
function SyncAPIClient(ClientPolicy $clientPolicy) {
$this->clientPolicy = $clientPolicy;
}
function SyncAPIClient($appKey, $appSecret) {
$this->clientPolicy = new ClientPolicy();
$this->clientPolicy->appKey=$appKey;
$this->clientPolicy->secKey=$appSecret;
}
}
My questions are
1.) If you check the function in SyncAPIClient, you will notice that the ClientPolicy class was passed as a parameter before a variable, what does it really mean? What is the essence of passing a class in function parameter?
2.) I am getting an error "Cannot redeclare SyncAPIClient::SyncAPIClient()" in my script log and the reason is that SyncAPIClient function was called twice in SyncAPIClient class. How can I solve this issue? Is there any better way to write this SyncAPIClient function instead of passing it twice?
The author of this script is nowhere to be found and I am left to fix it.
1) Here the $clientPolicy variable that is passed to this function, needs be a ClientPolicy instance.
In this way, if the argument that is passed is different from an instance of ClientPolice class, an error is generated.
function SyncAPIClient(ClientPolicy $clientPolicy) {
$this->clientPolicy = $clientPolicy;
}
https://wiki.php.net/rfc/typed_properties_v2
https://laravel-news.com/php7-typed-properties
2) The error Cannot redeclare SyncAPIClient::SyncAPIClient() is caused because you are trying to declare two functions called SyncAPIClient ().
If in first SyncAPIClient() method you just want save the $clientPolicy in $this->clientPolicy, you can use the magic method __construct. Or just try changing the name of one of the functions, and the problem should be a problem.
class SyncAPIClient{
__construct(ClientPolicy $clientPolicy) {
$this->clientPolicy = $clientPolicy;
}
function SyncAPIClient($appKey, $appSecret) {
$this->clientPolicy = new ClientPolicy();
$this->clientPolicy->appKey=$appKey;
$this->clientPolicy->secKey=$appSecret;
}
}
https://www.php.net/manual/en/language.oop5.decon.php
http://www.zentut.com/php-tutorial/php-constructor-and-destructor/
Hope this helps!
I would've fix the code you have like this:
class SyncAPIClient
{
private $clientPolicy = null;
function SyncAPIClient(ClientPolicy $clientPolicy = null)
{
if($clientPolicy instanceof ClientPolicy){
$this->clientPolicy = $clientPolicy;
}else{
$this->clientPolicy = new ClientPolicy();
}
}
public function setAuthParams($appKey, $appSecret) {
$this->clientPolicy->appKey=$appKey;
$this->clientPolicy->secKey=$appSecret;
}
}
This way you can instantiate a SyncAPIClient with or without a ClientPolicy.
Without ClientPolicy:
$syncAPI = new SyncAPIClient();
$syncAPI->setAuthParams($apiKey, $apiSecret);
With ClientPolicy:
$clientPolicy = new ClientPolicy();
$clientPolicy->appKey=$appKey;
$clientPolicy->secKey=$appSecret;
$syncAPI = new SyncAPIClient($clientPolicy);
When using class and functions in combination like
Rtin::
Functions nested inside that class Rtin should have different names than that class name
So you shouldn't have function called rtin
However you can call function from outside the class with it's name
From the error you have may be due to:
function you nested in the class or the function outside the class has a duplicate outside the script itself. Like having function mentioned in included function.php file and also mentioned in the script itself so php get confused because function name is written in two php files at the same time
Example of class
class Rtin{
private $data;
private $results;
public function getResultsType(){
return ........
}
}
To call class use
$q = Rtin::getResultsType($data['name']);
In your example. Adapt it to the example I have provide and review the included files for duplicate function .
I have seen in Laravel calling multiple method in the single line, example:
DB::get('test')->toJson();
I have a cool class and view method in that class.
$this->call->view('welcome')->anotherMethod();
I would like to call another method also? Where should I make that method?
DB::get() seems to be a method returning an object, where you can call other functions (I think a result object of a database query). If you want to call multiple functions on one object in one line, you have to return $this in your functions, e.g.:
class View {
public static function factory {
// The question is: How useful is this factory function. In fact: useless in
// the current state, but it can be extended in any way
return new self;
}
public function one() {
// do something
return $this;
}
public function two() {
// do something
return $this;
}
}
Then you can do:
$class = new View();
$class->one()->two();
// it's also possible to use the `factory` function
// you should think about, how useful this approach is in your application
$class = View::factory()->one()->two();
That's how you can do it in php, if laravel has some helpers for that, i can't say :)
When I am using CodeIgniter to implement a small application, I want all business checking functions in controllers could be defined outside the controller for more flexible.
The checking functions just like session checking, user information completion checking, or has user post an article, and so on.
Firstly, I tried to use helper to implement. In my core controller which extended from CI_Controller I wrote a check function:
protected function check () {
$this->checked = TRUE;
$methods = func_get_args();
foreach ($methods as $method) {
$m = 'check_' . $method;
if (!function_exists($m)) {
$this->load->helper("filters/$m");
}
if ($m() === FALSE) {
return FALSE;
}
}
return TRUE;
}
Then in any controller I can use this method to check my business logic like this:
public function something ()
if (!$this->check('session')) {
return $this->relogin();
}
// ...
if (!$this->check('userinfo')) {
return $this->redirect('settings');
}
// ...
if (!this->check('has_post')) {
// ...
}
// ...
}
But it has a problem that all helper function are global, and can't invoke protected functions in $CI instance. I didn't find a way how to invoke a instance function outside like JavaScript's call/apply.
So I turned to check the hook document of CI. But I don't think it helps, because the hook point can't be inside of any controller functions. It must be outside.
At last, I can just fallback to put all checking functions into core controller class. So I wonder is there any way to use interceptor as in Java structs?
You can use _remap()!
add a function into the class:
_remap($method, $params=[]) {
if (true) {
$this->$method($params);
} else {
$this->method5();
}
}
The logic is that everytime someone call a Method, the API would FIRST execut the REMAP function... inside you can do whatever you need and then decide if the API should execute the called method or another or none...
Where should I put the function that loads a model and Display a view but that is not accessible from the URL. I mean, I need to write a function that should call from the view and this function displays a menu list.
function displayMenu () {
$menu = $this->model->getMenuResults();
$this->load->view( 'ViewResults', $menu);
}
Should I write this as a private function in the main controller?
You can use private functions in codeigniter controller
private function _displayMenu()
{
$menu = $this->model->getMenuResults();
$this->load->view( 'ViewResults', $menu);
}
Straight from documentation
Private Functions
In some cases you may want certain functions hidden from public access. To make a function private, simply add an underscore as the name prefix and it will not be served via a URL request. For example, if you were to have a function like this:
private function _utility()
{
// some code
}
Trying to access it via the URL, like this, will not work:
example.com/index.php/blog/_utility/
For more details go to http://ellislab.com/codeigniter/user-guide/general/controllers.html#private
Put it in one of your helper functions like this
function displayMenu () {
$CI = &get_instance();
//choose whichever is appropriate
//option 1
//if your model is globally loaded then simply call the model like this
//$menu = $CI->loadedmodel->getMenuResults();
// option 2 otherwise load the model here
//$CI->load->model('model_name');
//$menu = $CI->model_name->getMenuResults();
$CI->load->view( 'ViewResults', $menu);
}
Well, I don't know if this post have the correct title. Feel free to change it.
Ok, this is my scenario:
pluginA.php
function info(){
return "Plugin A";
}
pluginB.php
function info(){
return "Plugin B";
}
Finally, I have a plugin manager that is in charge of import all plugins info to pool array:
Manager.php
class Manager
{
protected $pool;
public function loadPluginsInfo()
{
$plugin_names = array("pluginA.php", "pluginB.php");
foreach ($plugin_names as $name)
{
include_once $name;
$this->pool[] = info();
}
}
}
The problem here is that when I print pool array it only show me the info on the first plugin loaded. I supposed that the file inclusing override the info because it still calling the info() method from the first include.
Is there a way to include the info of both plugins having the info() function with the same name for all plugins files?
Thank you in advance
PS: a fatal cannot redeclare error is never hurled
you can use the dynamic way to create plugin classes
plugin class
class PluginA
{
public function info()
{
return 'info'; //the plugin info
}
}
manager class
class Manager
{
protected $pool;
public function loadPluginsInfo()
{
$plugin_names = array("pluginA", "pluginB"); //Plugin names
foreach ($plugin_names as $name)
{
$file = $name . '.php';
if(file_exists($file))
{
require_once($file); //please use require_once
$class = new $name(/* parameters ... */); //create new plugin object
//now you can call the info method like: $class->info();
}
}
}
}
Are you sure the interpreter isn't choking w/ a fatal error? It should be since you're trying to define the info function twice here.
There are many ways to achieve what you want, one way as in #David's comment above would be to use classes, eg.
class PluginA
{
function info() { return 'Plugin A'; }
}
class PluginB
{
function info() { return 'Plugin B'; }
}
then the Manager class would be something like this:
class Manager
{
protected $pool;
public function loadPluginsInfo()
{
$plugin_names = array("PluginA", "PluginB");
foreach ($plugin_names as $name)
{
include_once $name . '.php';
$this->pool[] = new $name();
}
}
}
Now you have an instance of each plugin class loaded, so to get the info for a plugin you would have $this->pool[0]->info(); for the first plugin. I would recommend going w/ an associative array though so you can easily reference a given plugin. To do this, the assignment to the pool would become:
$this->pool[$name] = new name();
And then you can say:
$this->pool['PluginA']->info();
for example.
There are many other ways to do it. Now that 5.3 is mainstream you could just as easily namespace your groups of functions, but I would still recommend the associative array for the pool as you can reference a plugin in constant time, rather than linear.