Jump to content

What's with the Wire() function?


CaelanStewart
 Share

Recommended Posts

Hi All,

Just a quick one, not a big issue.

To access API variables from inside a function with ProcessWire, I believe is a tad tedious.

Having to do this, just to access a few variables is a bit annoying, and frankly repetitive:

$page = Wire('page');
$sanitizer = Wire('sanitizer');
$user = Wire('user');
$users = Wire('users');
$input = Wire('input');

When it'd be much easier (and faster, and less typo prone) to do this:

global $page, $sanitizer, $user, $users, $input;

I've seen the possibility of confusion mentioned before as a reason against this. But let's be realistic, if somebody is writing templates and making use of the ProcessWire API, they are going to know off the top of their head exactly which API variables they need. In fact, I purposefully avoid declaring variables that have the same name as PWs API variables when I'm writing PW templates.

So my question really is: Why not?

Link to comment
Share on other sites

Because it breaks as soon as you're using any external code that uses these variable names anywhere. The WirePDF module for example does use mpdf as pdf rendering library. If this library is using $page as variable somewhere it's break your website.

@Mike

It's using the same object but it's still repetitive to use this snippet in each function or rewrite code from using variables to wire("var") when it's abstracted into a function.

  • Like 1
Link to comment
Share on other sites

Because it breaks as soon as you're using any external code that uses these variable names anywhere. The WirePDF module for example does use mpdf as pdf rendering library. If this library is using $page as variable somewhere it's break your website.

@Mike

It's using the same object but it's still repetitive to use this snippet in each function or rewrite code from using variables to wire("var") when it's abstracted into a function.

I somewhat disagree. The library may well try and define a class called 'Page' for instance, or a function called 'Wire' as much as it would the $page variable.

And plus, consider the following code:

<?php

global $hello;

$hello = "hello";

function goodbye() {
	$hello = "goodbye";	
}

echo $hello;

goodbye();

echo $hello;

The output is not "hellogoodbye" but is in fact "hellohello" as the '$hello' variable was never instantiated with the 'global' keyword inside the function. So unless this library sets the variable in the root scope, or also uses a global named '$hello' or '$page', then there will be no problem.

Yes, all said ways are repetitive, but I find the cleanness and brevity of the 'global' keyword approach preferable.

Link to comment
Share on other sites

Global variables are against the principle of object oriented programming. LostKobrakai made a good point. One could always write something like this:

$_GLOBALS['page'] = "I'm a string page";

and your code breaks...

If you're in a class derived from wire, the cleanest way to get the API variables is like this:

$this->wire('page');
$this->wire('sanitizer');

// They could also be accessed directly, but then you're not 100% sure if the member is overwritten with something else

$this->page
$this->sanitizer

The global wire function is there to access the API variables in (global) functions, or static methods when you're in a class. You don't even need to reassign them to local scoped variables, just use them like so:

echo wire('page')->id;

... or if you really want local variables with a one liner, write a little wrapper like this:

function getApiVars() {
  return array(
    wire('page'),
    wire('pages'),
    wire('sanitizer'),
  );
}

// And then
list($page, $pages, $sanitizer) = getApiVars();

Or another possibility would be to inject them into your class/method, if you don't subclass Wire.

Cheers

  • Like 8
Link to comment
Share on other sites

It's true that class collisions can happen, but pw 3.0 is moving to using namespaces for that reason. In turn variables are not namespaced. They are always bound to the scope or global. Wanze's helper method is probably a better way to go, kinda like extending Wire to get access to api variables in classes.

  • Like 2
Link to comment
Share on other sites

Global variables are against the principle of object oriented programming. LostKobrakai made a good point. One could always write something like this:

$_GLOBALS['page'] = "I'm a string page";

and your code breaks...

If you're in a class derived from wire, the cleanest way to get the API variables is like this:

$this->wire('page');
$this->wire('sanitizer');

// They could also be accessed directly, but then you're not 100% sure if the member is overwritten with something else

$this->page
$this->sanitizer

The global wire function is there to access the API variables in (global) functions, or static methods when you're in a class. You don't even need to reassign them to local scoped variables, just use them like so:

echo wire('page')->id;

... or if you really want local variables with a one liner, write a little wrapper like this:

function getApiVars() {
  return array(
    wire('page'),
    wire('pages'),
    wire('sanitizer'),
  );
}

// And then
list($page, $pages, $sanitizer) = getApiVars();

Or another possibility would be to inject them into your class/method, if you don't subclass Wire.

Cheers

Thank your for taking the time to clear that up. I have been enlightened!

  • Like 1
Link to comment
Share on other sites

  • 8 years later...

I just realized and then this was already in the Google SERP open from searching "wire in wire function processwire" regarding something else (wire('config') in a function was not a function because the namespace wasn't present):

wire() in the init method of a module which extends ProcessPageAdd in a different PW instance that is instantiated in ready.php is initialized also in the instance instantiating the other instance. For example:

 
wire()->addHookBefore("ProcessPageAdd::execute", $this, 'hookPageAdd');

resulted in an error adding a page of the same template name in the instance instantiating the other one. Prepending with $this-> disables the cross-site functionality.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...