3
\$\begingroup\$

Just wondering if this is okay to do? I have to store some PHP variable values into LocalStorage.

if($res->status == "success"){
 echo '<script>alert("alrighty sparky! lets get you in...");</script>';
 echo '<script>localStorage.setItem("token", JSON.stringify({"token": "'.$res->token.'" }))</script>';
 echo '<script>localStorage.setItem("username", JSON.stringify({"username": "'.$data->username.'" }))</script>';
 echo '<script>localStorage.setItem("id", JSON.stringify({"id": "'.$data->id.'" }))</script>';
 $boarding_url = base_url() . 'index.php/boarding/teddies';
 redirect($boarding_url);
 }
asked Jan 20, 2016 at 10:08
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

No, it doesn't work like that because you're not escaping your PHP strings to be a safe JavaScript string. What you're doing is encoding them as JSON but if - for example - $res->token contains \ then it will produce a broken JavaScript string and JSON.stringify() won't fix it.

Correct code must use json_encode() for this purpose.

echo '<script>localStorage.setItem("id", "'.json_encode($data->id).'")</script>';

Also note that you don't need to repeat <script> tag each time:

echo '<script type="text/javascript">';
// Write all lines here, don't forget semicolon at the end of each one
echo 'localStorage.setItem("id", "'.json_encode($data->id).'");';
echo '</script>';
answered Jan 20, 2016 at 11:58
\$\endgroup\$
2
\$\begingroup\$

As noted in the answer by Adriano Repetti, as you are outputing raw data into the javascript source, you could create invalid javascript. For example a quote in $res->token could create the following syntax error:

<script>localStorage.setItem("token", JSON.stringify({"token": "token with a " (quote)" }))</script>';

The SO highlighter makes this error quite obvious.

Aslo, as pointed out by Adriano, php's json_encode() takes care of this nicely.

However, whenever i find myself mixing js with a server side language, i endevour to keep the interleaving to an absolute minimum, to reduce confusion.

With that in mind, i would format the data in php, then output it a single place, creating an object that js can process:

if($res->status == "success"):
 $jsData = [
 'storageData' =>[
 'token' => $res->token,
 'username' => $res->username,
 'id' => $res->id
 ],
 'redirectUrl' => base_url() . 'index.php/boarding/teddies'
 ];
 ?>
 <script>
 var data = <?php echo json_encode($jsData);?>;
 for(var item in data.storageData){
 localStorage.setItem(item, storageData[item]);
 }
 //redirect
 window.location.replace(data.redirectUrl);
 </script>
<?php
endif;

(Unfortunately the SO syntax highlighter is not so clever here..)

With regards to the redirect:

redirect($boarding_url);

Presumably this function is also outputting javascript (as a regular header redirect would be impossible at this point, as the response body has already been sent), so for clarity i included redirect in the above js block.

Additionaly, this looks like a bit of a code smell - returning a response to the browser just to set some js data then performing another request back to the server.

saving the data in session, redirecting directly to the final destination (index.php/boarding/teddies) and have that page retrieve its data from session would probably make more sense, but thats another question.

answered Jan 20, 2016 at 14:17
\$\endgroup\$
2
  • \$\begingroup\$ Much apprecitated! Thanks Steve. I had this session option under consideration but the infrastructure been developed so far is making me to follow localstorage instead of session. I will make changes in the infrastructure in future and change this localstorage into session. Thanks again! \$\endgroup\$ Commented Jan 21, 2016 at 5:37
  • 1
    \$\begingroup\$ My upv, I like this, less mixing means less typos you will search for hours! \$\endgroup\$ Commented Jan 22, 2016 at 8:21

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.