как передать переменную из шаблона php в javascript

У меня есть страница, на которой я хочу отобразить некоторые точки на карте. У меня есть маленькие шаблоны (типа Smarty, но полегче) и там в шаблоне у меня есть переменная $points, состоящая из координат нужных мне точек. Мне нужно передать их в javascript (потому что только javascript может отображать эту карту с точками).

У меня есть 3 варианта как это сделать. Можете сказать, что лучше?

1-й способ: (Шаблон со вставкой javascript-тегов с глобальной переменной)

файл tpl.php:

<script>
MAP_POINTS = <?php echo json_encode($this->points); ?>;
</script>

.js-файл

function renderMap(){
var points = MAP_POINTS; // using global. Is it really bad? or who cares? =))
}

2-й способ: (передача переменной через элемент HTML)

tpl.php.файл

<input type="hidden" 
       value="<?php echo json_encode($this->points); ?>" 
       id="map_points_container">

.js-файл

function renderMap(){
// without globals, but needed to be parsed on local side
var points = $.parseJSON ( $( "#map_points_container" ).val() );
}

3-й способ: (способ AJAX)

Я вообще не передаю $this->points из файла шаблона. У меня есть другой файл .php, который обрабатывает все мои запросы AJAX:

Ajaxing.php

function get_map_points($params){
// some operations
return json_encode ($map_points);
}

И чем на локальной стороне у меня будет что-то вроде этого:

.js-файл

$.post ( 'ajaxing.php', params, 
         function(points){
           renderMap(points);
         }, 'json');

Третий способ обычный, но если я уже передаю какие-то значения из шаблона на локальную страницу, то могу передать и точки карты. На самом деле мне не нужно делать еще один запрос только для этой точки карты (поэтому я не люблю третий способ)

Но, может быть, вы посоветуете мне другой способ? лучший способ?

Способ, который я выбрал:

1-й способ с небольшими замечаниями. Весь мой код «рендеринга карты» находится в другом файле и выглядит примерно так:

$(function(){

MAP_APP = {};
MAP_APP.some_prop = null; // some properties
MAP_APP.some_method = function(){}; // some methods

});

Итак, в файле шаблона мне нужно только расширить свой объект MAP_APP:

<script>
MAP_APP.points = <?php echo json_encode($this->points); ?>;
</script>

Да, глобальная переменная. Но это как пространство имен всего приложения.

Спасибо всем.


person Larry Cinnabar    schedule 07.06.2011    source источник
comment
лучший по каким критериям?   -  person    schedule 07.06.2011
comment
Главные критерии — скорость и производительность. Второй критерий — это correctness кода. Я бы не хотел, чтобы мой код называли «странным», «необычным» или как-то еще;)   -  person Larry Cinnabar    schedule 07.06.2011
comment
Вот один из способов: Передача переменной php   -  person Ibu    schedule 07.06.2011
comment
@Ibu, проблема в том, что я делаю еще один запрос в БД. В файле .php, который сгенерировал шаблон, у меня есть запрос к БД и есть данные. Итак, в этом новом файле .php (который генерирует файл .js) я должен снова запросить эти данные.   -  person Larry Cinnabar    schedule 07.06.2011


Ответы (6)


Первый способ определенно наименее сложный и быстрый.

Второй добавляет дополнительный шаг обработки (parseJSON()), в котором нет необходимости.

Третий способ хорош, если вы имеете дело с большим количеством данных, которые являются необязательными (т.е. нужны только в том случае, если пользователь запрашивает их, и нет 100% уверенности, что это произойдет) или динамическими. Однако он создает новый запрос и не будет немедленно доступен.

Если вы не хотите использовать глобальные переменные, вы можете, например. оберните ваши функции JavaScript в объект и заполните свойство объекта из PHP:

<script>
MyObject.MAP_POINTS = <?php echo json_encode($this->points); ?>;
</script>
person Pekka    schedule 07.06.2011
comment
Я думал об этом. Это похоже на пространство имен... спасибо - person Larry Cinnabar; 07.06.2011

Есть еще один забавный способ передачи переменных во внешний файл js :)

Ваш PHP-файл:

<script type='text/javascript' src='script.js?id=0&some=<?php echo $whatever?>'></script>

и внутри вашего script.js вы можете получить эти значения:

var scripts = document.getElementsByTagName('scripts');

// get your current script;
for (var i=0,l=scripts.length;i<l;i++){
   if(scripts[i].src.indexOf('script.js') !== -1) { // or your script name
      var query = scripts[i].src.substr(scripts[i].src.indexOf('?')+1);
      // now you can split the query and access the values you want
      ....
   }
}
person Ibu    schedule 07.06.2011
comment
Интересная идея, но она нарушает кеширование JS-файла. - person Pekka; 07.06.2011
comment
Это правильно, если кэширование является проблемой - person Ibu; 07.06.2011
comment
до сих пор я не понимаю ... как вы можете получить $some и $id в файле сценария и что это за «скрипты» ?! - person Mac Taylor; 19.06.2011
comment
@Mac Taylor: вы можете просто разделить query из = и получить значение ключа - person Ibu; 20.06.2011

Первый из них самый эффективный и быстрый. Второй фанковый. С третьим тоже все в порядке.

Первый, потому что он не требует никаких других запросов. Второй немного странный, я бы не стал использовать такие конструкции, но это не значит, что нельзя. С третьим тоже все в порядке, но вам следует подумать о том, подходит ли вам AJAX. Если ваше приложение требует нескольких запросов точек для разных местоположений, то это может быть наиболее эффективным способом.

person Arend    schedule 07.06.2011

Я бы выбрал ваш второй метод, поскольку вы не хотите использовать для него AJAX (и кажется странным использовать AJAX для чего-то, что у вас уже есть на текущей странице). Вы хотите ограничить количество глобальных переменных в своем JavaScript, потому что все в вашем JavaScript будет создавать экземпляр каждой глобальной переменной и, таким образом, снижать вашу производительность.

Я забыл имя человека, но человек, который занимался оптимизацией в Yahoo! а затем пошел работать в Google, прочитал лекцию об оптимизации JavaScript, и это было одним из его пунктов.

EDIT: нашел ссылку: http://sites.google.com/site/io/even-faster-web-sites

person Jon    schedule 07.06.2011
comment
Может быть, вы говорите о Дугласе Крокфорде, не так ли? знак равно - person Larry Cinnabar; 07.06.2011
comment
Я бы не стал использовать второй способ - вы избегаете глобального, но вместо этого должны анализировать текстовое содержимое в JSON, что намного, намного хуже с точки зрения производительности. - person Pekka; 07.06.2011

С точки зрения скорости 1-й способ - лучший.

Но лучший способ — создать вывод XML из PHP и загрузить этот XML в Javascript через Ajax. Лучшим примером этого является статья, приведенная в документации по картам Google — http://code.google.com/apis/maps/articles/phpsqlajax_v3.html

person Rohit Singh Sengar    schedule 07.06.2011

По-другому:

In script_that_defines_renderMap.js:

function renderMap(points) {
  // take "points" as an argument
}

А потом:

<script src="script_that_defines_renderMap.js"/> 
<script>
  var mapPoints = <?php echo json_encode($this->points); ?>;
  renderMap(mapPoints);
</script>

Нет глобальной переменной, нет проблемы.

person Jordan Running    schedule 07.06.2011