首页 > 解决方案 > 用 php 下载 svg

问题描述

我想为 svg 创建一个 php 下载。Rn 我正在创建一个 svg 段,现在我想将该段放入下载中,但不知道如何。

有下载部分(download.php)及其从 index.php 加载代码


$file =  include('index.php');

header('Content-Disposition: attachment; filename="segment.svg"');
header('Content-Type: image/svg');
header('Content-Length: ' . strlen($file));
header('Connection: close');

echo $file;
exit();

有index.php

<body>
<div class="container">
    <form action="index.php" method="get">
        <label for="segments">Segmente</label><br/>
        <input type="number" id="segments" name="segment">
        <input type="submit" value="Absenden" name="submit">
    </form>
<?php

$getSegment = $_GET['segment'];

// I deleted some code here

            <svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" id="svg">
                <?php for ($i = 0; $i < 1; $i++): ?>
                    <?php
                    $start_angle = $segment_arc * $i;
                    $end_angle = $segment_arc * ($i + 1);
                    ?>
                    <path fill="#red" stroke-width="0" d="<?php echo $generate_arc($start_angle, $end_angle) ?>" />
                <?php endfor ?>
            </svg>
        </div>
    <div class="container">
        <button class="btn btn-primary" onclick="location.href='download.php'">Download</button>
    </div>
</body>
        <?php
    }
    echo segment_circle($getSegment);
} else if (!isset($getSegment) || empty($getSegment)) {
    echo 'Bitte trag eine Segmentanzahl ein!';
}

有一张它在前端的样子 在此处输入图像描述

标签: phpsvgdownload

解决方案


这是我没有 PHP 代码的 JavaScript 解决方案,我在对您的问题的评论中快速解释了这一点。

为什么要在 JS 中这样做?

JS解决方案的优势

  • 没有 HTTP 调用,因此服务器上没有处理。这将节省 CPU 并为最终用户更快。

  • 您的页面可能包含多个 SVG 图像,您不需要在服务器端处理这种情况。我的 JS 解决方案处理多个 SVG 图像和下载按钮。

  • 顺便说一句,SVG 本身可以直接用 JS 生成,而不是用 PHP 生成。

JS方案的缺点

  • 如果浏览器没有启用 JS,那么它将无法工作。但这可能非常罕见。

您总是可以选择 PHP 解决方案。我们会让你自己做。无论如何,我们还没有得到您的 PHP 代码。我也不明白你的 PHP 循环for ($i = 0; $i < 1; $i++):,这意味着你只做一次,所以循环不是必需的。

JS 解决方案的工作原理

  1. 您在 SVG 图像和下载按钮周围添加一些 HTML 标记。如果您的页面中有多个,这会将它们分开。我还添加了一个data-filename属性,以便您可以轻松设置不同的文件名。如果未设置该属性,则它会下降到在常量中设置的默认值。

  2. JavaScript 代码将在下载按钮上添加一个单击事件处理程序。当单击触发此选项时,它将执行以下操作:

    1. 创建一个<a>元素。
    2. 将 SVG 代码放入href属性中。
    3. download属性设置为具有良好的文件名。
    4. 使其<a>不可见并将其添加到 DOM。
    5. 在其上模拟单击事件以启动下载。
    6. 从 DOM 中删除<a>元素,因为我们不再需要它。

代码和工作演示

我在这里创建了一个 Codepen.io:Download a SVG with JS

这是用于阅读的复制粘贴解决方案。

注意:它不适用于最新版本的ChromeEdge(可能是Safari)上的 Stackoverflow 片段,因为出于安全原因,iframe 中禁用了下载

但它可以在您的网站上运行,因为它没有嵌入到<iframe>.

// An SVG file has an XML header which you don't use if the SVG is in the HTML document.
// As we want to generate a file, we'll add it before the <svg> tag to be compliant.
const SVG_XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>';

// The default SVG filename in case the data-filename attribute isn't set.
const DEFAULT_SVG_FILENAME = 'cake.svg';

// Get all the SVG containers of the page.
let svg_containers = document.querySelectorAll('.svg-container');

// For each SVG container, we'll bind the click event to the button to download the SVG.
svg_containers.forEach(function (svg_container, i) {
  let svg_image = svg_container.querySelector('.svg-image');
  // Let's get an optional filename from the data-filename attribute.
  let svg_filename = svg_image.getAttribute('data-filename') || DEFAULT_SVG_FILENAME;
  // The SVG code is the XML header and the trimmed inner HTML of the <div class="svg-image">.
  let svg_code = SVG_XML_HEADER + "\n" + svg_image.innerHTML.trim();
    
  // Now we want to bind the click event to the button so that it can download the SVG code above.
  // First let's get the <button>.
  let download_button = svg_container.querySelector('button');
  // Add the "click" handler on it.
  download_button.addEventListener('click', function (event) {
    // To do the "download" we need to do create a <a> element and click on it:
    // Create the <a> element.
    var a = document.createElement('a');
    // Set it's href to have the SVG content directly in the URL.
    a.setAttribute('href', 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg_code));
    // Set the filename for the "save as" dialog box.
    a.setAttribute('download', svg_filename);
    // Don't display this link in the HTML page.
    a.style.display = 'none';
    // Put it in the HTML page so that we can click on it.
    document.body.appendChild(a);
    // This click will generate the download.
    a.click();
    // Remove the created link from the HTML page.
    document.body.removeChild(a);
  });
});
html, body {
  margin: 0;
  padding: 0;
}

.grid {
  display: flex;
  flex-wrap: wrap;
}

.svg-container {
  text-align: center;
  margin: 1em;
  padding: 1em;
  border: 1px solid silver;
}
<div class="grid">

  <div class="svg-container">
    <div class="svg-image" data-filename="charkle_cake.svg">
      <svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" id="svg">
        <path d="M100,100 h-90 a90,90 0 1,0 90,-90 z"
              fill="gray" stroke="black" stroke-width="2" />
      </svg>
    </div>
    <button class="btn btn-primary">Download</button>
  </div>

  <div class="svg-container">
    <div class="svg-image" data-filename="strawberry_cake.svg">
      <svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" id="svg">
        <path d="M100,100 h-90 a90,90 0 1,0 90,-90 z"
              fill="#fee" stroke="red" stroke-width="2"
              transform="rotate(225, 100, 100)" />
      </svg>
    </div>
    <button class="btn btn-primary">Download</button>
  </div>

  <div class="svg-container">
    <div class="svg-image">
      <svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" id="svg">
        <path d="M100,100 h-90 a90,90 0 1,0 90,-90 z"
              fill="#efe" stroke="green" stroke-width="2"
              transform="rotate(135, 100, 100)" />
      </svg>
    </div>
    <button class="btn btn-primary">Download</button>
  </div>

</div>


推荐阅读