1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-08 07:47:00 +02:00

Add lazy-loading option to WireInput, specified by $config->wireInputLazy=true;

This commit is contained in:
Ryan Cramer
2018-06-28 12:29:50 -04:00
parent b54b3bace1
commit cccc2d1161
5 changed files with 157 additions and 17 deletions

View File

@@ -831,7 +831,21 @@ $config->maxPageNum = 999;
*/ */
$config->wireInputOrder = 'get post'; $config->wireInputOrder = 'get post';
/**
* Lazy-load get/post/cookie input into $input API var?
*
* This is an experimental option for reduced memory usage when a lot of input data is present.
*
* This prevents PW from keeping separate copies of get/post/cookie data, and it instead works
* directly from the PHP $_GET, $_POST and $_COOKIE vars.
*
* This option is also useful in that anything you SET to PWs $input->get/post/cookie also gets
* set to the equivalent PHP $_GET, $_POST and $_COOKIE.
*
* @var bool
*
*/
$config->wireInputLazy = false;
/*** 7. DATABASE ********************************************************************************/ /*** 7. DATABASE ********************************************************************************/

View File

@@ -83,6 +83,7 @@
* @property int $maxUrlSegmentLength Maximum length of any individual URL segment (default=128). #pw-group-URLs * @property int $maxUrlSegmentLength Maximum length of any individual URL segment (default=128). #pw-group-URLs
* @property int $maxUrlDepth Maximum URL/path slashes (depth) for request URLs. (Min=10, Max=60) #pw-group-URLs * @property int $maxUrlDepth Maximum URL/path slashes (depth) for request URLs. (Min=10, Max=60) #pw-group-URLs
* @property string $wireInputOrder Order that variables with the $input API var are handled when you access $input->var. #pw-group-HTTP-and-input * @property string $wireInputOrder Order that variables with the $input API var are handled when you access $input->var. #pw-group-HTTP-and-input
* @property bool $wireInputLazy Specify true for $input API var to load input data in a lazy fashion and potentially use less memory. Default is false. #pw-group-HTTP-and-input
* *
* @property bool $advanced Special mode for ProcessWire system development. Not recommended for regular site development or production use. #pw-group-system * @property bool $advanced Special mode for ProcessWire system development. Not recommended for regular site development or production use. #pw-group-system
* @property bool $demo Special mode for demonstration use that causes POST requests to be disabled. Applies to core, but may not be safe with 3rd party modules. #pw-group-system * @property bool $demo Special mode for demonstration use that causes POST requests to be disabled. Applies to core, but may not be safe with 3rd party modules. #pw-group-system

View File

@@ -447,7 +447,8 @@ class ProcessWire extends Wire {
$session = $this->wire('session', new Session($this), true); $session = $this->wire('session', new Session($this), true);
$this->initVar('session', $session); $this->initVar('session', $session);
$this->wire('user', $users->getCurrentUser()); $this->wire('user', $users->getCurrentUser());
$this->wire('input', new WireInput(), true); $input = $this->wire('input', new WireInput(), true);
if($config->wireInputLazy) $input->setLazy(true);
// populate admin URL before modules init() // populate admin URL before modules init()
$config->urls->admin = $config->urls->root . ltrim($pages->getPath($config->adminRootPageID), '/'); $config->urls->admin = $config->urls->root . ltrim($pages->getPath($config->adminRootPageID), '/');

View File

@@ -74,6 +74,14 @@ class WireInput extends Wire {
*/ */
protected $pageNum = 1; protected $pageNum = 1;
/**
* Use lazy loading method for get/post/cookie?
*
* @var bool
*
*/
protected $lazy = false;
/** /**
* @var array * @var array
* *
@@ -95,6 +103,18 @@ class WireInput extends Wire {
$this->useFuel(false); $this->useFuel(false);
$this->unregisterGLOBALS(); $this->unregisterGLOBALS();
} }
/**
* Set for lazy loading
*
* Must be called before accessing any get/post/cookie input
*
* @param bool $lazy
*
*/
public function setLazy($lazy = true) {
$this->lazy = (bool) $lazy;
}
/** /**
* Retrieve a named GET variable value, or all GET variables (from URL query string) * Retrieve a named GET variable value, or all GET variables (from URL query string)
@@ -121,7 +141,7 @@ class WireInput extends Wire {
*/ */
public function get($key = '') { public function get($key = '') {
if(is_null($this->getVars)) { if(is_null($this->getVars)) {
$this->getVars = $this->wire(new WireInputData($_GET)); $this->getVars = $this->wire(new WireInputData($_GET, $this->lazy));
$this->getVars->offsetUnset('it'); $this->getVars->offsetUnset('it');
} }
return $key ? $this->getVars->__get($key) : $this->getVars; return $key ? $this->getVars->__get($key) : $this->getVars;
@@ -150,7 +170,7 @@ class WireInput extends Wire {
* *
*/ */
public function post($key = '') { public function post($key = '') {
if(is_null($this->postVars)) $this->postVars = $this->wire(new WireInputData($_POST)); if(is_null($this->postVars)) $this->postVars = $this->wire(new WireInputData($_POST, $this->lazy));
return $key ? $this->postVars->__get($key) : $this->postVars; return $key ? $this->postVars->__get($key) : $this->postVars;
} }
@@ -166,7 +186,7 @@ class WireInput extends Wire {
* *
*/ */
public function cookie($key = '') { public function cookie($key = '') {
if(is_null($this->cookieVars)) $this->cookieVars = $this->wire(new WireInputData($_COOKIE)); if(is_null($this->cookieVars)) $this->cookieVars = $this->wire(new WireInputData($_COOKIE, $this->lazy));
return $key ? $this->cookieVars->__get($key) : $this->cookieVars; return $key ? $this->cookieVars->__get($key) : $this->cookieVars;
} }
@@ -604,6 +624,20 @@ class WireInput extends Wire {
return $this->httpHostUrl() . $this->url($withQueryString); return $this->httpHostUrl() . $this->url($withQueryString);
} }
/**
* Same as httpUrl() method but always uses https scheme, rather than current request scheme
*
* See httpUrl() method for argument and usage details.
*
* @param bool $withQueryString
* @return string
* @see WireInput::httpUrl()
*
*/
public function httpsUrl($withQueryString = false) {
return $this->httpHostUrl(true) . $this->url($withQueryString);
}
/** /**
* Get current scheme and URL for hostname without any path or query string * Get current scheme and URL for hostname without any path or query string
* *
@@ -611,11 +645,30 @@ class WireInput extends Wire {
* *
* #pw-group-URLs * #pw-group-URLs
* *
* @param string|bool|null Optionally specify this argument to force a particular scheme (rather than using current):
* - boolean true to force “https”
* - boolean false to force “http”
* - string with scheme you want to use
* - blank string or "//" for no scheme, i.e. URL begins with "//" which refers to current scheme.
* - omit argument or null to use current request scheme (default behavior).
* @return string * @return string
* *
*/ */
public function httpHostUrl() { public function httpHostUrl($scheme = null) {
return $this->scheme() . '://' . $this->wire('config')->httpHost; if($scheme === true) {
$scheme = 'https://';
} else if($scheme === false) {
$scheme = 'http://';
} else if(is_string($scheme)) {
if(strlen($scheme)) {
if(strpos($scheme, '//') === false) $scheme = "$scheme://";
} else {
$scheme = '//';
}
} else {
$scheme = $this->scheme() . '://';
}
return $scheme . $this->wire('config')->httpHost;
} }
/** /**

View File

@@ -16,7 +16,7 @@
* *
* Each WireInputData is not instantiated unless specifically asked for. * Each WireInputData is not instantiated unless specifically asked for.
* *
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer * ProcessWire 3.x, Copyright 2018 by Ryan Cramer
* https://processwire.com * https://processwire.com
* *
* @link http://processwire.com/api/ref/input/ Offical $input API variable documentation * @link http://processwire.com/api/ref/input/ Offical $input API variable documentation
@@ -70,16 +70,40 @@ class WireInputData extends Wire implements \ArrayAccess, \IteratorAggregate, \C
*/ */
protected $data = array(); protected $data = array();
/**
* Are we working with lazy data (data by reference)?
*
* @var bool
*
*/
protected $lazy = false;
/**
* When lazy mode is active, these are keys of values set in a non-lazy way
*
* @var array
*
*/
protected $unlazyKeys = array();
/** /**
* Construct * Construct
* *
* @param array $input Associative array of variables to store * @param array $input Associative array of variables to store
* @param bool $lazy Use lazy loading?
* *
*/ */
public function __construct(array $input = array()) { public function __construct(&$input = array(), $lazy = false) {
$this->useFuel(false); $this->useFuel(false);
$this->stripSlashes = get_magic_quotes_gpc(); $this->stripSlashes = get_magic_quotes_gpc();
$this->setArray($input); if(!empty($input)) {
if($lazy) {
$this->data = &$input;
$this->lazy = true;
} else {
$this->setArray($input);
}
}
} }
/** /**
@@ -101,7 +125,19 @@ class WireInputData extends Wire implements \ArrayAccess, \IteratorAggregate, \C
* *
*/ */
public function getArray() { public function getArray() {
return $this->data; if($this->lazy) {
$data = array();
foreach($this->data as $key => $value) {
if(isset($this->unlazyKeys[$key])) {
$data[$key] = $value;
} else {
$data[$key] = $this->__get($key);
}
}
return $data;
} else {
return $this->data;
}
} }
/** /**
@@ -112,9 +148,13 @@ class WireInputData extends Wire implements \ArrayAccess, \IteratorAggregate, \C
* *
*/ */
public function __set($key, $value) { public function __set($key, $value) {
if(is_string($value) && $this->stripSlashes) $value = stripslashes($value); if(is_string($value)) {
if(is_array($value)) $value = $this->cleanArray($value); if($this->stripSlashes) $value = stripslashes($value);
} else if(is_array($value)) {
$value = $this->cleanArray($value);
}
$this->data[$key] = $value; $this->data[$key] = $value;
if($this->lazy) $this->unlazyKeys[$key] = $key;
} }
/** /**
@@ -154,12 +194,40 @@ class WireInputData extends Wire implements \ArrayAccess, \IteratorAggregate, \C
* *
*/ */
public function __get($key) { public function __get($key) {
// if($key == 'whitelist') return $this->whitelist;
return isset($this->data[$key]) ? $this->data[$key] : null; if(strpos($key, '|')) {
$value = null;
foreach(explode('|', $key) as $k) {
$value = $this->__get($k);
if($value !== null) break;
}
return $value;
} else if(isset($this->data[$key])) {
$value = $this->data[$key];
if($this->lazy && !isset($this->unlazyKeys[$key])) {
// in lazy mode, value is not cleaned until it is accessed
if(is_string($value)) {
if($this->stripSlashes) $value = stripslashes($value);
} else if(is_array($value)) {
$value = $this->cleanArray($value);
}
}
} else {
$value = null;
}
return $value;
} }
public function getIterator() { public function getIterator() {
return new \ArrayObject($this->data); if($this->lazy) {
$data = $this->getArray();
return new \ArrayObject($data);
} else {
return new \ArrayObject($this->data);
}
} }
public function offsetExists($key) { public function offsetExists($key) {
@@ -176,6 +244,7 @@ class WireInputData extends Wire implements \ArrayAccess, \IteratorAggregate, \C
public function offsetUnset($key) { public function offsetUnset($key) {
unset($this->data[$key]); unset($this->data[$key]);
if($this->lazy && isset($this->unlazyKeys[$key])) unset($this->unlazyKeys[$key]);
} }
public function count() { public function count() {
@@ -183,12 +252,14 @@ class WireInputData extends Wire implements \ArrayAccess, \IteratorAggregate, \C
} }
public function remove($key) { public function remove($key) {
unset($this->data[$key]); $this->offsetUnset($key);
return $this; return $this;
} }
public function removeAll() { public function removeAll() {
$this->data = array(); $this->data = array();
$this->lazy = false;
$this->unlazyKeys = array();
return $this; return $this;
} }