Email address as argument to controller view method

Kinda thought I was getting to grips with cakePHP 3.x but how little it turned out I knew.

My index.ctp displays a table of address information.
One of the columns in this table is an email address.
I create links in the table which (when clicked) calls this controller’s view method with the email address as argument.
However CakePHP (or browser) returns error message: Resource cannot be found on the server. The URL is also modified and the email part has the ‘@’ replaced by %40 (not so unexpected)
The problem is the email address itself, and the fact that it ends in .com or
If I use a different column (not an email address) in the links it all works as expected.
With an email address as argument the view method isn’t even called. I just get the error message as shown above.
I believe this problem to be pretty basic stuff but haven’t be able to find an answer online.
Any help appreciated.

You need to urlencode what you put into the URL, and urldecode what you take out.

With the ‘how’ addressed, I’m scratching my head over the ‘why’.

Assuming a typical index-page to detail/view-page transition; I wonder why you don’t have a nice convenient record id to use as the key-value in your link.


Thanks for the reply dreamingmind.
If i were coding an application in earnest I would indeed be using ‘id’.
As I said in my original post all other columns work (including id) but not an email address.
Because I’m still experimenting I’d love to know why I can’t pass an email address to a controller’s view method (or as I suspect, to any other controller method).
The link doesn’t even reach the view method when clicked. Just displays 'resource not found on server.

Thanks for your reply Zuluru.
When I use Html->link() to create the link it must use urlencode as the email address is modified by replacing the ‘@’ with %40.
Problem is that clicking the link does not even get to the controller’s view method. So can’t debug with pr() etc. Craeting the links with id or any other table column work fine.

Hmm, for some reason I thought that urlencode would also encode the period, which the link function won’t. But I guess not, and now don’t know why I would have thought that… It’s almost certainly the period that’s causing problems, so if you manually escape that, you should be okay. Reason being that it’s going to be seeing “.com” (or whatever) at the end and thinking that this is the file extension, and Cake doesn’t think it should be handling all those “file types”.

Yes, you are spot on with that Zuluru.
Did a str_replace() converting ‘.’ to %2e before forming the link and that did the trick.
Underlying the Html->link() I suspect urlencode was called to replace the ‘@’ and the ‘%’ that I had inserted. So the link looked at bit strange but it all worked fine.

Interestly at the controller’s view method (or during the path to the view method by cakephp) urldecode must be automatically called as i’m left with a properly formed emal address in the passed in email argument.
Thanks for your help…

Using $this->Url->build() would also allow passing email addresses as GET param properly. I had a similar problem once and solved it with the following code:

	href="<?= $this->Url->build([
		'plugin' => 'XX',
		'controller' => 'XXXX', 
		'action' => 'X', 
	]) ?>" 
	<?= __('Next'); ?>	
1 Like

Thanks dmuenstermann
Unfortunately your example code gives me exactly the same issue.
I added this to the controller index method:
href="<?= $this->Url->build([
‘action’ => ‘View’,
]) ?>"

<?= __('Next'); ?>

Clicking on this link produces:
The requested resource /addresses/view/ was not found on this server. So clearly the ‘.’ is still causing problems.

I’m using CakePHP 3.7
str_replace(’.’, ‘0x2e’, $email); // Using this before forming the link provides a fix.

I’d be grateful for any further info.

I’m wondering about that - as the mentioned code works for me (also using cake 3.7).
Can you please post your routes.php and controller function?

Hi dmuenstermann
Sorry for the long delay in replying.

It starts with this link in index.ctp

  • <?= $this->Html->link('email_link', ['action'=>'view', $users->first()->email]) ?>
  • As you know when this link is clicked it should call the controller’s view action with the email as argument.
    But it never gets there and I get the error message: Resource cannot be found on the server
    This is the controller view function:
    public function view($email=null)
    $user = $this->Users->findByEmail($email)->firstOrFail();
    $this->set(‘user’, $user);

    By changing the index.ctp link code to this - it all works fine.

  • <?= $this->Html->link('enail_link', ['action'=>'view', str_replace('.', '%2e', $users->first()->email)]) ?>
  • my routes file is the default 3.7 routes.php file. Not changed by me.