Reputation: 7
Rewording the previous PHP/JavaScript question regarding access to an external JavaScript function from within a PHP script.
I am trying to access a JavaScript function MyJsFnct
which is a part of MyJs.js
JavaScript file from MyPhp.php
PHP script.
I am using Windows7, Internet Explorer 11.0.9600, and XAMPP-V3.2.1 with PHP-5.5.9.
My Web root directory is C:\Apache-Php-MySql\htdocs
.
MyPhp.php
and MyJs.js
are in C:\Apache-Php-MySql\htdocs\My-Php-Scripts
.
Here is a skeleton of MyPhp.php
, and MyJs.js
which contains the JavaScript function MyJsFnct
.
Note, MyPhp.php
and MyJs.js
are parts of a very large PHP/JavaScript project which contains several hundreds lines of code. I narrowed the problem down to just the code that does not work. Since the skeleton code is a part of a much larger project, I can't just replace the PHP code with HTML code, or replace the link with a button. I need to find out why the PHP code can't access the JavaScript function.
The actual project is taken from PHP and MySQL for Dynamic Web Sites, 4th edition, by Larry Ullman, chapter 11, "PHP and JavaScript".
MyPhp.php
<!DOCTYPE html>
<html lang ="en">
<head>
<title>Page-Php-Js</title>
<meta http equiv="content-type" content ="text/html; charset=UTF-8" />
<script type="text/javascript" charset="utf-8" src="MyJs.js"> </script>
</head>
<body>
<?php
print "<a href=\"javascript:MyJsFnct()\">Click</a> to call JS function (MyJsFnct)";
?>
</body>
</html>
MyJs.js
function MyJsFnct() {
/* some code that lets me know that
the JavaScript function has been called */
}
Related question, is there a way to determine which JavaScript function has been called?
When using the debugger (F12 Developer Tools), the PHP page looks OK with 0
errors, warnings, or messages, but when I click on the JavaScript link I get the following error: 'MyJsFnct' is undefined
.
Upvotes: 1
Views: 577
Reputation: 53597
This isn't the answer you were hoping for, but: you're doing things really wrong, and this will hopefully help you get things at least closer to right.
Step one is to know where PHP runs, where JavaScript runs, and what HTML should look like.
Based on what you've shown, you're not using actual PHP code, so we don't need any kind of <?php ... ?>
tags and then string escaping. Anywhere.
what you really should have is a plain index.php file that is for all intents and purposes, just html:
<!doctype html>
<html lang ="en">
<head>
<title>Page-Php-Js</title>
<meta charset="utf-8">
<script src="MyJs.js"></script>
</head>
<body>
<button onclick="MyJsFnct()">Click</button>
</body>
</html>
There is no PHP code in here, because you're not using anything PHP. Requesting index.php
will simply straight up pass this through. Also note that this is proper HTML5, unlike your source: <meta>
has a charset attribute, the format you used is HTML 4.01. That would be fine if you said you were using HTML 4.01, but the <!doctype html>
instruction explicitly tells browsers "this is HTML5!". Further, meta
is not />
closed. <script>
elements don't need a type
for javascript (neither do <style>
elements for css).
You also used an <a>
as if it's a button - there is a <button>
element so use that instead. Only use an <a>
if you actually link out to another resource (either URL or a #FragmentIdentifier). If you don't want it to look like a button, that's irrelevant: it's about the semantic role. If you can click it, to cause JS to do something, it's a <button>
and then you use some CSS to make it look however you need (including just plain text. Button styling is just some creative background/foreground/border coloring by browsers and fully overridable).
Now, PHP is going to do nothing here. It runs on the server, and generates your content on request by someone's browser. It gets transfered - PHP now dies. Literally, its process is killed and the server now waits for more new request. If those are for PHP files, it will start PHP up again, which will again die once it's generated the data request.
So the page it sent is no longer under PHP control: it now lives in a browser, "client-side", on the computer of whoever asked for the URL. That can be you, on the same computer that's running PHP, but in terms of "what controls the data" that doesn't matter: PHP died, your browser go the data. Now we're in HTML+JavaScript-only territory.
So, fixing your JavaScript: do not use document.write
. It's an ancient, obsolete JS call that absolutely doesn't do what you think it does. If you thought it wrote data into the page, then you can yell at whoever told you to use it: that is not what it does. What it actually does is pump data into an active data stream, and if there isn't one, it makes a new data stream for the browser to work with. That means that if you call it any time after your page has loaded, it wipe the entire page clean, and starts a new write stream for the browser to decode. You page will be gone. It's a terrible function and you should never, ever, use it.
(There are times when you do want to use it. Those times are extremely rare, and usually very low level and almost always related to workin on the browser as a file system or stream interpreter. And even then typically it's a bad idea)
What you actually want is DOM manipulation. So instead of a MyJs.js
with this:
function MyJsFnct() {
document.write ("Now inside JS function (MyJsFnct)</br></br>");
}
you actually want this:
function MyJsFnct() {
var p = document.createElement("p");
p.textContent = "This paragraph was written by my JavaScript function";
document.body.appendChild(p);
}
This builds a new paragraph the proper way, assigns it some text content (don't be tempted to use innerHTML
if there is no HTML. And if there is HTML, you're probably unwittingly baking in a potential exploit right there). Then the paragraph is added to the end of your page. Done.
Finally, don't use <br>
elements. This is a holdover from when we didn't have very useful CSS, and we needed special elements to add vertical spacing. We do that with CSS now, and <br>
is literlly for when you need a semantic line break. So not visually, but for when a machine reader should see that a line has to be terminated early and resumed a next line for whatever reason. Under normal circumstances, there are no such reasons.
Upvotes: 4