Reading a value from application.ini - php

I have a value that's defined in application.ini
conditions.time= 50
How can I read it in an zend action the zend way?

You can use Zend_Config_Ini
$config = new Zend_Config_Ini('my/ini/file.ini');
echo $config->conditions->time; // 50

Here is my approach, which you can use anywhere in the application:
class My_Controller_Action_Helper_Options extends Zend_Controller_Action_Helper_Abstract
{
/**
* Options separator delimiterm e.g.
* option.subkey or
* option/subkey
*/
const DELIMITER = '.';
/**
* Retrieve application options from bootstrap
*
* #return array
*/
public function getOptions()
{
$front = $this->getFrontController();
$bootstrap = $front->getParam('bootstrap');
if (null === $bootstrap) {
throw new Exception('Unable to find bootstrap');
}
return $bootstrap->getOptions();
}
/**
* Get array key if exists, otherwise returns null
*
* #param array $values
* #param string $key
* #return mixed
*/
private static function _getValue($values, $key)
{
if (is_array($values) && isset($values[$key])) {
return $values[$key];
}
return null;
}
/**
* Get application option form bootstrap
*
* #example
* $options = Zend_Controller_Action_HelperBroker::getStaticHelper('options')
* ->get('conditions.time', 'defaultvalue');
*
* #param string $section
* #param mixed $default
* #return Zend_Config
*/
public function get($section = null, $default = null)
{
$value = $this->getOptions();
if (null !== $section && is_string($section)) {
if (false === strpos($section, self::DELIMITER)) {
$value = $this->_getValue($value, $section);
} else {
$sections = explode(self::DELIMITER, $section);
foreach ($sections as $section) {
$value = $this->_getValue($value, $section);
if (null === $value) {
break;
}
}
}
}
if (null === $value) {
return $default;
}
return $value;
}
/**
* #param string $section
* #param mixed $default
* #return Zend_Config
*/
public function direct($section = null, $default = null)
{
return $this->get($section, $default);
}
}

The Application's Bootstrap.php has access to the application.ini using $this->getOptions(), you could store the value you want in your registry something like this:
public function _initConditions()
{
$config = $this->getOptions();
if (isset($config['conditions']))
{
$registry = Zend_Registry::getInstance();
$registry->conditions = $config['conditions'];
}
}
You could then access your conditions using the registry, in much the same way that you set them here.

Here is an action helper for that :
class My_Controller_Action_Helper_Config
extends Zend_Controller_Action_Helper_Abstract
{
/**
* #return array
*/
public function direct()
{
$bootstrap = $this->getActionController()->getInvokeArg('bootstrap');
$ns = strtolower(trim($bootstrap->getAppNamespace(), '_'));
return $bootstrap->getOption($ns);
}
}
You have to put your application namespace as a prefix :
; application.ini
My.conditions.time= 50
You can use it in a controller like this :
$config = $this->_helper->config();
$this->view->time = $config['conditions']['time'];

You might be able to use getenv('conditions.time')
http://www.php.net/manual/en/function.getenv.php

PHP has a parse_ini_file() function.

Related

How to disable _PHCR key pefixes used in Phalcon Redis backend

I'm using Phalcon Redis backend to store some data. I later try to access this data in Lua language embedded into nginx. What drives me crazy is that Phalcon adds some garbage prefixes to Redis keys and some terrible prefixes to values. So, if I store this pair in Redis - (abc, querty) - this is what is really stored:
(_PHCRabc, s:6:"querty")
Is it possible to disable all this garbage and continue working with Phalcon Redis backend?
According to the the source it is not possible to disable it with option: https://github.com/phalcon/cphalcon/blob/master/phalcon/cache/backend/redis.zep
public function get(string keyName, int lifetime = null) -> var | null
let lastKey = "_PHCR" . prefix . keyName;
public function save(keyName = null, content = null, lifetime = null, boolean stopBuffer = true) -> boolean
lastKey = "_PHCR" . prefixedKey,
Also quoting the docs:
This adapter uses the special redis key “_PHCR” to store all the keys
internally used by the adapter
I read somewhere that this is done in order to be able to flush Phalcon generated cache files.
Your best option would be to extend the \Phalcon\Cache\Backend\Redis class and overwrite the save/get methods. And after use your class in the service:
// Cache
$di->setShared('cache', function() use ($config) {
return new MyCustomRedis(
new \Phalcon\Cache\Frontend\Json(['lifetime' => 172800]), // 2d
$config->redis
);
});
You can override the redis adapter like this.
<?php
namespace App\Library\Cache\Backend;
use Phalcon\Cache\Exception;
class Redis extends \Phalcon\Cache\Backend\Redis
{
/**
* #var \Redis
*/
protected $_redis;
/**
* {#inheritdoc}
*
* #param string $keyName
* #param integer $lifetime
* #return mixed|null
*/
public function get($keyName, $lifetime = null)
{
$redis = $this->getRedis();
/**
* #var \Phalcon\Cache\FrontendInterface $frontend
*/
$frontend = $this->_frontend;
$lastKey = $this->getKeyName($keyName);
$this->_lastKey = $lastKey;
$content = $redis->get($lastKey);
if ($content === false) {
return null;
}
if (is_numeric($content)) {
return $content;
}
return $frontend->afterRetrieve($content);
}
/**
* {#inheritdoc}
*
* #param string $keyName
* #param string $content
* #param int $lifetime
* #param bool $stopBuffer
* #return bool
*
* #throws Exception
*/
public function save($keyName = null, $content = null, $lifetime = null, $stopBuffer = true)
{
if ($keyName === null) {
$lastKey = $this->_lastKey;
} else {
$lastKey = $this->getKeyName($keyName);
$this->_lastKey = $lastKey;
}
if (!$lastKey) {
throw new Exception('The cache must be started first');
}
$redis = $this->getRedis();
/**
* #var \Phalcon\Cache\FrontendInterface $frontend
*/
$frontend = $this->_frontend;
if ($content === null) {
$cachedContent = $frontend->getContent();
} else {
$cachedContent = $content;
}
/**
* Prepare the content in the frontend
*/
if (!is_numeric($cachedContent)) {
$preparedContent = $frontend->beforeStore($cachedContent);
} else {
$preparedContent = $cachedContent;
}
if ($lifetime === null) {
$tmp = $this->_lastLifetime;
$ttl = $tmp ? $tmp : $frontend->getLifetime();
} else {
$ttl = $lifetime;
}
$success = $redis->set($lastKey, $preparedContent);
if (!$success) {
throw new Exception('Failed storing the data in redis');
}
if ($ttl > 0) {
$redis->setTimeout($lastKey, $ttl);
}
$isBuffering = $frontend->isBuffering();
if ($stopBuffer === true) {
$frontend->stop();
}
if ($isBuffering === true) {
echo $cachedContent;
}
$this->_started = false;
return $success;
}
/**
* {#inheritdoc}
*
* #param string $keyName
* #return bool
*/
public function delete($keyName)
{
$redis = $this->getRedis();
$lastKey = $this->getKeyName($keyName);
return (bool)$redis->delete($lastKey);
}
/**
* {#inheritdoc}
*
* #param string $prefix
* #return array
*/
public function queryKeys($prefix = null)
{
$redis = $this->getRedis();
$pattern = "{$this->_prefix}" . ($prefix ? $prefix : '') . '*';
return $redis->keys($pattern);
}
/**
* {#inheritdoc}
*
* #param string $keyName
* #param string $lifetime
* #return bool
*/
public function exists($keyName = null, $lifetime = null)
{
$redis = $this->getRedis();
if ($keyName === null) {
$lastKey = $this->_lastKey;
} else {
$lastKey = $this->getKeyName($keyName);
}
return (bool)$redis->exists($lastKey);
}
/**
* {#inheritdoc}
*
* #param string $keyName
* #param int $value
* #return int
*/
public function increment($keyName = null, $value = 1)
{
$redis = $this->getRedis();
if ($keyName === null) {
$lastKey = $this->_lastKey;
} else {
$lastKey = $this->getKeyName($keyName);
}
return $redis->incrBy($lastKey, $value);
}
/**
* {#inheritdoc}
*
* #param string $keyName
* #param int $value
* #return int
*/
public function decrement($keyName = null, $value = 1)
{
$redis = $this->getRedis();
if ($keyName === null) {
$lastKey = $this->_lastKey;
} else {
$lastKey = $this->getKeyName($keyName);
}
return $redis->decrBy($lastKey, $value);
}
/**
* {#inheritdoc}
*
* #return bool
*/
public function flush()
{
}
/**
* Get Prefix
*
* #return string
*/
public function getPrefix()
{
return $this->_prefix;
}
/**
* Get Redis Connection
*
* #return \Redis
*/
public function getRedis()
{
$redis = $this->_redis;
if (!is_object($redis)) {
$this->_connect();
$redis = $this->_redis;
}
return $redis;
}
/**
* Get Key Name
*
* #param $keyName
* #return string
*/
protected function getKeyName($keyName)
{
return $this->_prefix . $keyName;
}
}

How do I pass the controller by other means than the url in PHP MVC

I realize this may be a dumb question, but I am struggling with a custom MVC project I started in order to learn PHP and I was not able to find what I was looking for anywhere else.
My question is, how do I pass the controller to my router, in a way that does not use the url. How would I make it so that the href in my link tags only provide the category and id and yet make it work. At the moment my urls look like this:
website/controller/method/args
ex: website/articles/post/13
I want the url to be like:
website/category/id-or-slug-from-title
I would really appreciate the help, since it's been bugging me for a week now.
Thanks in advance.
Well, it would be hard to describe possible steps in comment section, so I will add an answer.
The following steps will be exemplary and they do not describe the whole process. I will omit some details
Assuming that you're trying to implement MVC, you should have some kind of bootstrap.php (or something like that)
So, let's create our router class
/**
* Current method
* #var string
*/
protected $method;
/**
* Current args
* #var unknown
*/
protected $args = array();
private static $instance;
/**
* That's how we retrieve class instance
* #return app_router_http
*/
public static function getInstance()
{
if (!isset(static::$instance))
{
static::$instance = new self;
}
return static::$instance;
}
private function __clone() {}
/**
* #throws app_exception
*/
private function __construct()
{
/* парсим текущий урл */
$url = parse_url (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : "/", PHP_URL_PATH);
$url = preg_replace("/\\/{2,}/i", "/", $url);
/* Let's retrieve static route (for example - /category/id-or-slug-from-title) */
if ($_route = $this->getStaticRoute($url))
{
if ($_route->hasErrors())
{
throw new app_exception($_route->getErrors(";"));
}
$this
->setController($_route->getController())
->setMethod($_route->getMethod())
->setArgs($_route->getArgs() ? $_route->getArgs() : null)
;
return;
}
/* Let's retrive dynamic route, because we didn't fing static */
if ($_route = $this->getDynamicRoute($url))
{
if ($_route->hasErrors())
{
throw new app_exception($_route->getErrors(";"));
}
$this
->setController($_route->getController())
->setMethod($_route->getMethod())
->setArgs($_route->getArgs() ? $_route->getArgs() : null);
return;
}
throw new app_exception("Can't found any route objects", 503);
}
/**
* #param string $controller
* #return Router
*/
public function setController($controller)
{
$this->controller = $controller;
return $this;
}
/**
* #return string
*/
public function getController()
{
return $this->controller;
}
/**
* #param string $method
* #return Router
*/
public function setMethod($method)
{
$this->method = $method;
return $this;
}
/**
* #return string
*/
public function getMethod()
{
return $this->method;
}
/**
* #param array $args
* #return Router
*/
public function setArgs(array $args = null)
{
if (isset($args))
{
$this->args = $args;
}
return $this;
}
/**
* #return mixed
*/
public function getArgs()
{
return $this->args;
}
/**
* #param string $route
* #param string $controller
* #param string $method
* #param string $objectId
* #return Route|NULL
*/
public function getStaticRoute($route = null, $controller = null, $method = null, $objectId = null)
{
$db = new DB(); //Some class for db connections
if (isset($route) && !isset($controller) && !isset($method) && !isset($objectId))
{
$selector = "SELECT * FROM `routes` WHERE `route` = '".$db->escape($route)."'";
}
if (!isset($route) && isset($controller) && isset($method) && isset($objectId))
{
$selector = "SELECT * FROM `routes` WHERE `controller` = '".$db->escape($controller)."' && `method` = '".$db->escape($method)."' && `objectId` = '".$db->escape($objectId)."'";
}
if (!isset($selector))
{
throw new app_exception(get_class($this)."::getStaticRoute incorrect params", 503);
}
if ($db->query($selector)->rows())
{
$row = $db->fetch();
$object = new Router();
$object->setAttributes($row);
if (!$object->hasErrors())
{
$object->setController("{$object->getController()}");//Here we are setting our awesome controller
if (!$this->isControllerExist($object->getController()))
{
return $object->addError("Controller {$object->getController()} missing (static route: #{$object->getId()})");
}
if (!$this->isMethodExist($object->getController(), $object->getMethod()))
{
return $object->addError("Method {$object->getMethod()} missing (controller: {$object->getController()}) (static route: #{$object->getId()})");
}
}
return $object;
}
return null;
}
/**
* #param string $path
* #return Router
*/
public function getDynamicRoute($path)
{
$object = new Router;
//Here we will assume that our url looks like this /controller/method/args
/* Url fragments */
$fragments = explode("/", substr($path, 1));
//Removing trailing slash
if (!$fragments[sizeof($fragments)-1])
{
unset($fragments[sizeof($fragments)-1]);
}
if (!isset($fragments[0]))
{
$fragments[0] = APP_ROUTE_DEFAULT_CONTROLLER; //Some kind of magic constant
}
$controller = $fragments[0];
if(!class_exists($controller)
{
throw new Exception("Ooops, controller not found", 404);
}
array_shift($fragments); //We don't need controller element anymore
for ($i = 0; $i <= 1; $i++)
{
if ($i == 0)
{
$method = APP_ROUTE_DEFAULT_METHOD;//We also need to handle urls like /news. For example, each controllers has default method index()
}
else
{
$method = $fragments[0];
}
if ($this->isControllerExist($controller) && $this->isMethodExist($controller, $method))
{
return
$object
->setController($controller)
->setMethod($method);
}
}
return $object->addError("Can't route to <strong>".implode("/", $fragments)."</strong> (dynamic route for module <strong>{$module}</strong>)");
}
/**
* #param string $controller
* #return boolean
*/
public function isControllerExist($controller = null)
{
if (!isset($controller))
{
$controller = $this->getController();
}
return class_exists($controller);
}
/**
* #param string $controller
* #param string $method
* #return boolean
*/
public function isMethodExist($controller = null, $method = null)
{
if (!isset($controller))
{
$controller = $this->getController();
}
if (!isset($method))
{
$method = $this->getMethod();
}
return method_exists($controller, $method);
}
public function run()
{
$_str = $this->getController();
$controller = new $_str;
$return = call_user_func_array(array($controller, $this->getMethod()), $this->getArgs());
return $return;
}
}
So, in bootstrap.php you just need to need to make a call Router::getInstance()->run()
Static route will try to pass your params
For dynamic routes, you always can read args from $_REQUEST
P.S. To be true, this is a cutted examaple made from my old project

Cannot get css/js files to load using custom router

I've been working (mostly for fun) on a custom router.
It's a work in progress, so any advice is always welcome!
But my main problem is that de css/js files are not loaded anymore.
It looks like the path to the files is attached to the current url, so users/(css path).
In Chrome and Firefox the assets just keep loading, no response/code is returned. If I deliberately cause an exception to be thrown, such as altering the file path, I do see the html of the exception being returned.
I've done a lot of debugging already, and cannot seem to figure it out.
/**
* #var
*/
private $routes;
/**
* #var string
* Todo: add this to an ini file or something
*/
private $base_route = "/index.php";
/**
* #param $route
* #param $callback
* #param string $method
*/
public function addRoute($route, $callback, $method = Route::GET)
{
$routes = $this->getRoutes();
if (empty($routes) || !in_array($route, $routes)) {
$this->setRoute(
[
"route" => $route,
"callback" => $callback
], $method
);
return;
}
}
/**
* #param array $route
* #param $method
*/
public function setRoute(array $route, $method)
{
$this->routes[$method][] = $route;
}
/**
* #return mixed
*/
public function getRoutes()
{
return $this->routes;
}
/**
* #throws \Exception
*/
public function handle()
{
$route = $this->getURI();
$route = str_replace($this->base_route, "", $route);
$urlparts = explode("?", $route);
if (count($urlparts) > 1) {
$route = $urlparts[0];
$query = $urlparts[1];
}
if ($this->isAssetRoute($route)) {
$parts = explode("/", $route);
foreach ($parts as $part) {
if ($part !== "public") {
unset($parts[$part]);
} else {
continue;
}
}
$route = implode($parts);
return APP_PATH . "/" . $route;
}
if (empty($route)) {
$this->executeCallback("HomeController");
return;
}
$exists = false;
$routes = $this->getRoutes();
$requested_method = $this->getMethod();
if (!isset($routes[$requested_method])) {
throw new Exception("404: Route {$route} does not exist with method {$requested_method}");
}
$declared_routes = $routes[$requested_method];
$count_routes = count($declared_routes);
for ($i = 0; $i < $count_routes; $i++) {
if ($declared_routes[$i]["route"] === $route) {
$exists = true;
$data = $declared_routes[$i];
continue;
}
}
if (!$exists) {
throw new \Exception("404: route {$route} does not exist!");
}
//Todo: replace [var]
$route = $this->compileRoute($route);
$this->executeCallback($data["callback"]);
}
/**
* #return mixed
*/
private function getProtocol()
{
return $_SERVER["HTTPS"];
}
/**
* #return mixed
*/
public function getMethod()
{
return $_SERVER["REQUEST_METHOD"];
}
/**
* #return mixed
*/
public function getURI()
{
return $_SERVER["REQUEST_URI"];
}
/**
* #param $route
* #param $callback
*/
public function get($route, $callback)
{
$this->setRoute(
[
"route" => $route,
"callback" => $callback
], Route::GET
);
}
/**
* #param $route
* #param $callback
*/
public function post($route, $callback)
{
$this->setRoute(
[
"route" => $route,
"callback" => $callback
], Route::POST
);
}
/**
* #param $route
* #return mixed
*/
public function compileRoute(&$route)
{
$uri = explode("/", $_SERVER["REQUEST_URI"]);
$formatted_route = "";
foreach ($uri as $key => $param) {
$formatted_route .= "/" . preg_replace(
"/\[(.*)\]/", "1", $param
);
}
return str_replace($this->base_route, "", $formatted_route);
}
/**
* #param $callback
* #throws \Exception
*/
public function executeCallback($callback)
{
$callback_data = explode("::", $callback);
$controller = $callback_data[0];
if (!isset($callback_data[1])) {
$method = "index";
} else {
$method = $callback_data[1];
}
if (!class_exists($controller)) {
throw new \Exception("Class {$controller} does not exist!");
}
if (!method_exists($controller, $method)) {
throw new \Exception("Method {$method} does not exist!");
}
$controller::$method();
}
/**
* #param $route
* #return bool
*/
private function isAssetRoute($route)
{
return (stripos($route, "/public/assets/") !== false);
}
Solved it by getting the correct header for it (text/css or application/javascript for those wondering), echoing the file contents and then returning;
I put the code for that in the if ($this->isAssetRoute($route)) statement, located in the handle() method.
All other code in that statement is removed.

Kohana - display buffered views or custom view on shutdown

I am using Kohana View_Core derivative for my views. I would like to display buffered views or custom view on shutdown e.g.
If there were some errors/exceptions during the runtime => display error page
If executed with no errors => display the buffered output
The View
class View
{
private $file = '';
private $data = array();
private static $global_data = array();
public static $view = '';
private function __construct($file = FALSE, array $data = array())
{
if ($file !== FALSE)
{
$this->set_filename($file);
}
if (!empty($data))
{
$this->data = $data + $this->data;
}
}
/**
* Creates new view object and returns it.
*
* #param string filename
* #param array variables
* #return object View
*/
public static function factory($file = FALSE, array $data = array())
{
return new View($file, $data);
}
/**
* Captures the output that is generated when a view is included.
* The view data will be extracted to make local variables. This method
* is static to prevent object scope resolution.
*
* #param string filename
* #param array variables
* #return string
*/
public static function capture($view_filename, array $view_data)
{
extract($view_data, EXTR_SKIP);
ob_start();
try
{
require $view_filename;
}
catch (Exception $error)
{
$ob_handlers = ob_list_handlers();
if (!empty($ob_handlers))
{
ob_end_clean();
}
throw $error;
}
return ob_get_clean();
}
/**
* Load view file
*
* #param string filename
* #return boolean
* #return object View
*/
public function set_filename($file)
{
if (strpos($file, APP_DIR) === FALSE)
{
$extension = strrpos($file, '.') === FALSE ? '.php' : '';
$path = APP_DIR.DIR_SEP.'system'.DIR_SEP.'views'.DIR_SEP.$file.$extension;
}
else
{
$path = $file;
}
if (!file_exists($path))
{
Error::throw_throwable('Unable to find file '.$path);
}
$this->file = $path;
return $this;
}
/**
* Sets a global variable, similar to the set() method.
*
* #param string variable name
* #param mixed variable value
* #return object View
*/
public static function set_global($key, $value = FALSE)
{
self::$global_data[$key] = $value;
}
/**
* Assigns a variable by name.
*
* #param string variable name or an array of variables
* #param mixed variable value
* #return object View
*/
public function set($key, $value = FALSE)
{
if (is_array($key))
{
foreach ($key as $name => $value)
{
$this->data[$name] = $value;
}
}
else
{
$this->data[$key] = $value;
}
return $this;
}
/**
* Renders the view object to a string.
*
* #throws exception
* #param string filename
* #return string
*/
public function render($file = FALSE)
{
if ($file !== FALSE)
{
$this->set_filename($file);
}
if (empty($this->file))
{
Error::throw_throwable('Unable to find file '.$this->file);
}
$data = array_merge(View::$global_data, $this->data);
return View::capture($this->file, $data);
}
public function __toString()
{
try
{
$result = $this->render();
return $result;
}
catch (Exception $error)
{
Error::throw_throwable($error);
}
}
public function __set($key, $value)
{
$this->set($key, $value);
}
public function __get($key)
{
return isset($this->data[$key]) ? $this->data[$key] : FALSE;
}
}
Usage
$content = View::factory('main/Main')
->set('order', !empty($_SESSION['order']) ? $_SESSION['order'] : FALSE)
->set('order_success', $order_success)
->set('items', $items)
->set('weights', $weights)
->set('ammounts', $ammounts)
->set('prices', $prices)
->set('total_price', $total_price)
->set('validator', FALSE)
;
$template = $this->get_template();
echo $template->set('content', $content);
What the previous lines do is echo a content view inside of template view. And this should be also the result that my shutdown handler is echoing if necessary. Is there a nice/easy way to do this?
It sounds like what you want is to show a custom error page when there is an error. What I typically do here is to extend Kohana_Kohana_Exception class (as Kohana_Exception) and override the public static function handler method.
This lets you put in some code that can check what the error is (HTTP_404_Exception or other) what the environment is (dev / production) and do whatever behavior you want.
In my case, something like this:
// If not production and not an HTTP exception
if ( ! ($e instanceof HTTP_Exception) && Kohana::$environment !== Kohana::PRODUCTION)
{
// Use built in error handler to show stace trace for developers
Kohana_Kohana_Exception::handler($e);
// ... exit(1);
}
// Otherwise
$injected_routes = array(Route::get('error'));
echo Request::factory('error-uri', NULL, FALSE, $injected_routes)
->headers(Request::$initial->headers())
->execute()
->send_headers(TRUE)
->body();
Here you need another route called error that matches error-uri and goes to another error controller/action/view that you can use to render your custom error page.
For this to work you need to have errors enabled by passing 'errors' => TRUE to your Kohana::init call in bootstrap.php.

Zend framework - PDO source code

I have a little question just for educational purpose...
I was digging into Zend Framework's code, in order to learn how it works "from the inside", and I stopped at this little piece of code : (Their implementation of bindParam() from PDO) :
/**
* Binds a parameter to the specified variable name.
*
* #param mixed $parameter Name the parameter, either integer or string.
* #param mixed $variable Reference to PHP variable containing the value.
* #param mixed $type OPTIONAL Datatype of SQL parameter.
* #param mixed $length OPTIONAL Length of SQL parameter.
* #param mixed $options OPTIONAL Other options.
* #return bool
*/
public function bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
{
if (!is_int($parameter) && !is_string($parameter)) {
/**
* #see Zend_Db_Statement_Exception
*/
require_once 'Zend/Db/Statement/Exception.php';
throw new Zend_Db_Statement_Exception('Invalid bind-variable position');
}
$position = null;
if (($intval = (int) $parameter) > 0 && $this->_adapter->supportsParameters('positional')) {
if ($intval >= 1 || $intval <= count($this->_sqlParam)) {
$position = $intval;
}
} else if ($this->_adapter->supportsParameters('named')) {
if ($parameter[0] != ':') {
$parameter = ':' . $parameter;
}
if (in_array($parameter, $this->_sqlParam) !== false) {
$position = $parameter;
}
}
if ($position === null) {
/**
* #see Zend_Db_Statement_Exception
*/
require_once 'Zend/Db/Statement/Exception.php';
throw new Zend_Db_Statement_Exception("Invalid bind-variable position '$parameter'");
}
// Finally we are assured that $position is valid
$this->_bindParam[$position] =& $variable;
return $this->_bindParam($position, $variable, $type, $length, $options);
}
The thing that I don't understand, is that at the end of the function, they return
return $this->_bindParam($position, $variable, $type, $length, $options)
which is declared as an array ...
/**
* Query parameter bindings; covers bindParam() and bindValue().
*
* #var array
*/
protected $_bindParam = array();
How can they return an array and pass parameters to it ?
Moreover, I can find any condition to stop the recursion...
You can find the link for the file here :
http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Db/Statement.php
Zend_Db_Statement is an abstract class.
Unless I am mistaken, all classes that inherit from Zend_Db_Statement declare a _bindParam() method.
for example in Zend_Db_Statement_Pdo:
class Zend_Db_Statement_Pdo extends Zend_Db_Statement implements IteratorAggregate
{
...
protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
{
...
}
}

Categories