【问题标题】:Returning javascript results for use in php返回用于 php 的 javascript 结果
【发布时间】:2015-05-09 08:34:53
【问题描述】:

我有一个存储客户和员工的数据库。该数据库的前端使用非常旧的软件(从 90 年代后期开始在 vb6 中编码,所以我不能简单地对地址进行地理编码以便在输入时插入,除非我想做一些花哨的 sql 工作)。我正在为数据构建一些更强大的报告软件。我想在显示客户和员工居住地的软件中包含谷歌地图功能。当生成当前员工或客户的名册时,我还希望它检查新添加的内容,然后将他们的地址地理编码到数据库表中,以便我可以在以后的报告中引用它们。我对识别新条目或对其位置进行地理编码没有问题。

php 脚本的工作方式是检查客户端是否已经填充了纬度和经度信息,如果没有,则获取 lat/lng,然后将其插入数据库。如果有几个新客户/员工,我希望它遍历结果集并插入相关信息。问题是 google api 通过 javascript 获取 lat/lng,所以我不能将该信息传递回 php 脚本以将其存储到数据库中,我真的不想使用 javascript 来插入它。

所以我想知道解决这个问题的最佳方法。我已经研究和测试了几个小时了。我想我可能可以通过 ajax 技术传递变量,但是在循环中间这样做不会导致问题吗?

这里有一些示例代码,对于如此冗长的问题,我深表歉意!

地理编码的Javascript sn-p:

function codeAddress(address) {

  geocoder.geocode( { 'address': address}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
        var newlat = results[0].geometry.location.lat();
        var newlng = results[0].geometry.location.lng();
        alert(results[0].geometry.location);


    } else {
      alert('Geocode was not successful for the following reason: ' + status);
    }
  });

php sn-p:

$address = "";
$num = 0;
//Google geocode limits requests to 10 per second, limit to 5 total requests at a time.
//If more theres more than 10 clients who have yet to be geocoded, running the database insertion code
//---should provide long enough delay to geocode again and not hit the overflow limit


while ($row = mssql_fetch_array($result) and $num < 5) {
   if ($row['lat'] == "") {
        //Create address string
        $address = $row['Address1'] . " " . $row['City'] . ", NY " . $row['Zip'];
        $address = str_replace("'", "", $address);
       //Test to show addresses without lat/lng were pulled
        echo "<script>codeAddress('" . $address . "');</script>" . $address . "<br />";
        $num = $num + 1;
        }

    }

【问题讨论】:

  • 你为什么说“所以我不能将该信息传递回 php 脚本以将其存储到数据库中”?
  • 因为我的理解是php首先运行在服务器端,所以它在javascript代码之前运行,然后再运行。所以我不能只告诉 javascript 插入“这段 php 代码”,然后继续使用 php 脚本。这不是真的吗?
  • 确实如此,但您可以将结果提交到服务器上的 PHP 脚本,并使用该脚本将数据发布到数据库(正如您在帖子中所说,我不考虑“使用 AJAX 技术”,如果您不使用 XML 并且您没有将结果返回给客户端......)。您可以通过在返回的数据中包含标识符来解决“循环”问题。
  • 可以直接在php中调用api,比如:file_get_contents("http://maps.google.com/maps/api/geocode/json?sensor=false&amp;address=$addtress");
  • 像往常一样,答案总是很简单。我绝对可以简单地使用 http 请求来提取数据。谢谢史蒂夫

标签: javascript php mysql google-maps


【解决方案1】:

以下是将地址转换为地理坐标(纬度、语言)的代码:

<?php
      $Address = urlencode($Address);
      $request_url = "http://maps.googleapis.com/maps/api/geocode/xml?address=".$Address."&sensor=true";
      $xml = simplexml_load_file($request_url) or die("url not loading");
      $status = $xml->status;
      if ($status=="OK") {
          $Lat = $xml->result->geometry->location->lat;
          $Lon = $xml->result->geometry->location->lng;
          $LatLng = "$Lat,$Lon";
      }
    ?>

您可以使用简单的 SQL 查询将这些 Lat Lng 存储在数据库中,然后将其检索回以显示在地图上。为此,您必须显示地图。请参阅以下代码:

<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Google Maps Example</title>
        <style type="text/css">
            body { font: normal 14px Verdana; }
            h1 { font-size: 24px; }
            h2 { font-size: 18px; }
            #sidebar { float: right; width: 30%; }
            #main { padding-right: 15px; }
            .infoWindow { width: 220px; }
        </style>
        <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript">
        //<![CDATA[

        var map;

        // Ban Jelačić Square - Center of Zagreb, Croatia
        var center = new google.maps.LatLng(45.812897, 15.97706);

        function init() {

            var mapOptions = {
                zoom: 13,
                center: center,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            }

            map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

            var marker = new google.maps.Marker({
                map: map, 
                position: center,
            });
        }
        //]]>
        </script>
    </head>
    <body onload="init();">

        <h1>Places to check out in Zagreb</h1>

        <section id="sidebar">
            <div id="directions_panel"></div>
        </section>

        <section id="main">
            <div id="map_canvas" style="width: 70%; height: 500px;"></div>
        </section>

    </body>
</html>

从数据库中获取数据:

<?php

$server     = 'localhost';
$username   = 'root';
$password   = 'YOUR_PASSWORD';
$database   = 'YOUR_DATABASE';

$dsn        = "mysql:host=$server;dbname=$database";

现在创建您自己的文件,该文件将返回实际数据。

<?php

    require 'config.php';

    try {

        $db = new PDO($dsn, $username, $password);
        $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

        $sth = $db->query("SELECT * FROM locations");
        $locations = $sth->fetchAll();

        echo json_encode( $locations );

    } catch (Exception $e) {
        echo $e->getMessage();
    }

要在地图上显示位置,您必须发出 AJAX 请求:

function makeRequest(url, callback) {
    var request;
    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest(); // IE7+, Firefox, Chrome, Opera, Safari
    } else {
        request = new ActiveXObject("Microsoft.XMLHTTP"); // IE6, IE5
    }
    request.onreadystatechange = function() {
        if (request.readyState == 4 && request.status == 200) {
            callback(request);
        }
    }
    request.open("GET", url, true);
    request.send();
}

定义具有 JSON 响应的 init() 函数:

var map;

// Ban Jelačić Square - City Center
var center = new google.maps.LatLng(45.812897, 15.97706);

var geocoder = new google.maps.Geocoder();
var infowindow = new google.maps.InfoWindow();

function init() {

    var mapOptions = {
      zoom: 13,
      center: center,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }

    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

    makeRequest('get_locations.php', function(data) {

        var data = JSON.parse(data.responseText);

        for (var i = 0; i < data.length; i++) {
            displayLocation(data[i]);
        }
    });
}

最后你需要在地图上显示位置,你可以像这样添加一个信息窗口:

function displayLocation(location) {

    var content =   '<div class="infoWindow"><strong>'  + location.name + '</strong>'
                    + '<br/>'     + location.address
                    + '<br/>'     + location.description + '</div>';

    if (parseInt(location.lat) == 0) {
        geocoder.geocode( { 'address': location.address }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {

                var marker = new google.maps.Marker({
                    map: map, 
                    position: results[0].geometry.location,
                    title: location.name
                });

                google.maps.event.addListener(marker, 'click', function() {
                    infowindow.setContent(content);
                    infowindow.open(map,marker);
                });
            }
        });
    } else {
        var position = new google.maps.LatLng(parseFloat(location.lat), parseFloat(location.lon));
        var marker = new google.maps.Marker({
            map: map, 
            position: position,
            title: location.name
        });

        google.maps.event.addListener(marker, 'click', function() {
            infowindow.setContent(content);
            infowindow.open(map,marker);
        });
    }
}

希望这有帮助!

【讨论】:

  • 非常感谢 AniV。感谢史蒂夫的建议,我能够调整我的代码,将 lat/lng 作为 json 对象通过 php 拉出,但这对任何人来说都是一个很棒的参考,因为它显示了整个图片,所以向你致敬。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 2011-08-18
  • 2012-11-21
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多