【问题标题】:PHP functions in class are returning empty values类中的 PHP 函数返回空值
【发布时间】:2020-06-12 00:59:14
【问题描述】:

我正在使用一个 WordPress 插件,该插件将帖子显示为 Google 地图上的标记。网站前端使用定义的纬度和经度正确显示标记,但 WP 管理面板中的各个帖子部分缺少值。

插件在编辑器窗格中呈现地图的 JavaScript 文件中输出像 <?php echo esc_js($this->latitude()) ?><?php echo esc_js($this->longitude()) ?> 这样的纬度和经度。如前所述,这些不会为 Google 地图返回任何值。

在同一部分,但使用不同的代码,使用<?php esc_attr_e( $marker->latitude() )?><?php esc_attr_e( $marker->longitude() )?> 返回纬度和经度值。我附上了一张截图,展示了它的显示方式。默认情况下,地图使用全球纬度和经度来使标记居中。

当我var_dump 包含位置值的变量$marker_list 时,将返回纬度和经度值。

array(1) {
    [21]=>object(Marker)#11821(12) {
        ["id":"Marker":private]=>int(21)
        ["post_id":"Marker":private]=>int(406)
        ["is_main":"Marker":private]=>bool(!0)
        ["title":"Marker":private]=>string(16)"Vancouver Island"
        ["categories":"Marker":private]=>string(23)"a:1:{i:3;s:6:"canada";}"
        ["tags":"Marker":private]=>string(6)"a:0:{}"
        ["latitude":"Marker":private]=>float(49.4178)
        ["longitude":"Marker":private]=>float(-125.197)
        ["marker_logo_id":"Marker":private]=>int(10)
        ["infobox_descritpion":"Marker":private]=>string(367)"Text"
        ["infobox_image":"Marker":private]=>string(1)"0"
        ["infobox_style":"Marker":private]=>string(30)"novo-map_infobox_style_default"
    }
}

标记类

class Marker {
    /**
     * Unique id of the Marker object
     *
     * @access   private
     * @var      int
     * @since    1.0.0
     */
    private $id;

    /**
     * Id of the post where the marker was defined
     *
     * @access   private
     * @var      int
     * @since    1.0.0
     */
    private $post_id;

    /**
     * define if it is the main pin for a specific post
     * there should be only on main marker per post
     *
     * @access   private
     * @var      boolean
     * @since    1.0.0
     */
    private $is_main=true;

    /**
     * title of the marker
     *
     * @access   private
     * @var      string
     * @since    1.0.0
     */
    private $title;

    /**
     * Should reflect the categories (list of categories id) of the post_id
     *
     * @access   private
     * @var      string
     * @since    1.0.0
     */
    private $categories='';

    /**
     * Should reflect the tags (list og tags id) of the post id
     *
     * @access   private
     * @var      string
     * @since    1.0.0
     */
    private $tags='';

    /**
     * lattitude of the marker
     *
     * @access   private
     * @var      array
     * @since    1.0.0
     */
    private $latitude=0;

    /**
     * longitude of the marker
     *
     * @access   private
     * @var      array
     * @since    1.0.0
     */
    private $longitude=0;

    /**
     * marker_logo object attached to the marker
     *
     * @access   private
     * @var      object
     * @since    1.0.0
     */
    private $marker_logo_id=2;

    /**
     * description that appears in the infobox. Can be HTML
     *
     * @access   private
     * @var      string
     * @since    1.0.0
     */
    private $infobox_descritpion;

    /**
     * image id that should be displayed in the infobox
     * default value should not be changed as it is a small trick used later
     *
     * @access   private
     * @var      int
     * @since    1.0.0
     */
    private $infobox_image = -1;

    /**
     * infobox_style object attached to the marker
     *
     * @access   private
     * @var      string
     * @since    1.0.0
     */
    private $infobox_style='novo-map_infobox_style_default';

    /**
     * Marker constructor.
     * @param array $data
     * @since    1.0.0
     */
    public function __construct(array $data) {
        $this->hydrate($data);
    }

    /**
     * Hydrate the objects on construct with the given values.
     * The provided array should have the right structure
     *
     * @param array $data
     * @since    1.0.0
     */
    public function hydrate(array $data){
        foreach ($data as $key => $value) {
            //check if the key starts with novo-map- for unique names in wp admin
            if (substr( $key, 0, 16 ) === 'novo-map-marker-') {
                $key = str_replace('novo-map-marker-','',$key);
            }
            $method = 'set_'.$key;
            if (method_exists($this, $method)) {
                $this->$method($value);
            }
        }
    }

    /**
     * All getters and setters for the Marker class
     *
     * Data validation should occur in the setters
     */

    public function id() {
        return $this->id;
    }

    public function set_id($id) {
        $this->id = (int)$id;
    }

    public function post_id() {
        return $this->post_id;
    }

    public function set_post_id($post_id) {
        $this->post_id = (int)$post_id;
    }

    public function is_main() {
        return $this->is_main;
    }

    public function set_is_main($is_main) {
        $this->is_main = (bool)$is_main;
    }

    public function title() {
        return $this->title;
    }

    public function set_title($title) {
        $this->title = sanitize_text_field($title);
    }

    public function categories() {
        return $this->categories;
    }

    public function set_categories($categories) {
        $this->categories = (string)$categories;
    }

    public function tags() {
        return $this->tags;
    }

    public function set_tags($tags) {
        $this->tags = (string)$tags;
    }

    public function latitude() {
        return $this->latitude;
    }

    public function set_latitude($latitude) {
        $this->latitude = (float)$latitude;
    }

    public function longitude() {
        return $this->longitude;
    }

    public function set_longitude($longitude) {
        $this->longitude = (float)$longitude;
    }

    public function marker_logo_id() {
        return $this->marker_logo_id;
    }

    public function set_marker_logo_id($marker_logo_id) {
        $this->marker_logo_id = (int)$marker_logo_id;
    }

    public function infobox_description() {
        return $this->infobox_descritpion;
    }

    public function set_infobox_description($infobox_description) {
        $this->infobox_descritpion = wp_kses_post($infobox_description);
    }

    public function infobox_image() {
        return $this->infobox_image;
    }

    public function set_infobox_image($infobox_image) {
        $this->infobox_image = (string)$infobox_image;
    }

    public function infobox_style() {
        return $this->infobox_style;
    }

    public function set_infobox_style($infobox_style) {
        $this->infobox_style = (string)$infobox_style;
    }

    /**
     * generate the marker object part of the gmap script
     *
     * @since    1.0.0
     */
    public function generate_script($gmap, $gmap_name, $infobox_style_list) {
        //generate the script from template
        ob_start();
        include( plugin_dir_path(dirname( __FILE__ )) .'public/partials/marker-script.php' );
        $marker_script = ob_get_contents();
        ob_end_clean();
        echo fn_minify_js($marker_script);
    }
}

我将如何调试 PHP 以找出为什么没有返回值?

【问题讨论】:

  • 应该echo esc_js($this->latitude()) 只是echo esc_js($marker->latitude())
  • @Phil 进行此更改会导致 Google 地图无法在帖子编辑器中正确加载,并会破坏其他插件功能。如前所述,$this->latitude() 代码在前端地图标记渲染中正常工作。

标签: javascript php wordpress google-maps


【解决方案1】:

我认为esc_js 接受字符串值。 $this->latitude()$this->longitude() 数据类型为 float。你应该把它们转换成string

试试这个。它可能会帮助你

<?php echo esc_js($this->latitude().'') ?>
<?php echo esc_js($this->longitude().'') ?>

【讨论】:

  • 在这种情况下,使用 esc_js 不是一个好主意。 esc_js 的目标是转义字符串,而不是浮动
【解决方案2】:

esc_js 函数只接受字符串,如here 解释的那样

您需要将浮点值转换为字符串,如下所示。

<?php
echo esc_js((string)$this->latitude());
echo esc_js((string)$this->longitude());

【讨论】:

  • 我实现了你的代码,但问题仍然存在。问题似乎与 PHP 类有关,并在此上下文中使用 $this。如果我将 lat 和 long 值硬编码到文件中,Google 地图的标记就会正确放置。
  • 你能用整个类的源代码编辑你的问题,然后我可以看到上下文的问题在哪里
  • 我已经用完整的 Marker 类更新了我的问题。
  • 正在调查 :)
【解决方案3】:

您发送一个“浮点数”,但 esc_js 需要一个“字符串”。在这种情况下,我建议不要使用esc_js 函数。所以:

如果您 100% 确定您的类型始终是“浮点数”。您可以直接显示您的价值:

<?php echo $this->longitude() ?>

但是!如果你不能 100% 确定,为了防止 XSS 攻击,你可以像这样强制浮点类型(另见 floatval):

<?php echo (float) $this->longitude() ?>

如果您想尊重原始演员表,另一种可能的方法是使用json_encode,如下所示:

<?php echo json_encode($this->longitude()) ?>

第二种方式,大概就是你想做的吧。

【讨论】:

  • 我已经测试了您的答案,但不幸的是它们不起作用。出于某种原因,来自 Marker 类的值不适用于 $this 上下文。请查看我原来问题中的标记类,看看是否存在问题。
  • 是的,$marker-&gt;latitude() 阻止地图部分呈现。 $this-&gt;latitude() 上下文适用于地图插件的前端,而不是后端。
  • 我们可能缺少有关您的问题的信息。您是否尝试过将 $marker 和 $this 分别保留在使用它们的位置?
  • 我已经用在地图上显示标记的工作前端代码更新了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-06
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多