سؤال

لقد كنت أحاول استخدام SQLite مع غلاف PDO في PHP بنجاح متباين.يمكنني القراءة من قاعدة البيانات بشكل جيد، ولكن لا يتم الالتزام بأي من تحديثاتي بقاعدة البيانات عندما أعرض الصفحة في المتصفح.من الغريب أن تشغيل البرنامج النصي من صدفتي يؤدي إلى تحديث قاعدة البيانات.كنت أظن أن أذونات الملف هي السبب، ولكن حتى مع توفير قاعدة البيانات الوصول الكامل (chmod 777)، استمرت المشكلة.هل يجب أن أحاول تغيير مالك الملف؟إذا كان الأمر كذلك، ماذا؟

بالمناسبة، جهازي هو التثبيت القياسي لنظام التشغيل Mac OS X Leopard مع تفعيل PHP.

@ توم مارتن

شكرا لك على الرد.لقد قمت للتو بتشغيل الكود الخاص بك ويبدو أن PHP يعمل كمستخدم _www.حاولت بعد ذلك تحويل قاعدة البيانات إلى _www، لكن ذلك لم ينجح أيضًا.

يجب أن أشير أيضًا إلى أن وظيفة errorInfo الخاصة بشركة تنمية نفط عمان لا تشير إلى حدوث خطأ.هل يمكن أن يكون هذا إعدادًا مع فتح PDO بطريقة أو بأخرى لقاعدة البيانات للقراءة فقط؟لقد سمعت أن SQLite يقوم بإجراء تأمين الكتابة على الملف بأكمله.هل من الممكن أن تكون قاعدة البيانات مقفلة بشيء آخر يمنع الكتابة؟

لقد قررت تضمين الكود المعني.سيكون هذا أكثر أو أقل ميناء السيناريو جرانت إلى PHP.حتى الآن هو مجرد قسم الأسئلة:

<?php

$db = new PDO('sqlite:test.db');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://stackoverflow.com/users/658/kyle");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIE, "shhsecret=1293706652");
$page = curl_exec($ch);

preg_match('/summarycount">.*?([,\d]+)<\/div>.*?Reputation/s', $page, $rep);
$rep = preg_replace("/,/", "", $rep[1]);

preg_match('/iv class="summarycount".{10,60} (\d+)<\/d.{10,140}Badges/s', $page, $badge);
$badge = $badge[1];

$qreg = '/question-summary narrow.*?vote-count-post"><strong.*?>(-?\d*).*?\/questions\/(\d*).*?>(.*?)<\/a>/s';
preg_match_all($qreg, $page, $questions, PREG_SET_ORDER);

$areg = '/(answer-summary"><a href="\/questions\/(\d*).*?votes.*?>(-?\d+).*?href.*?>(.*?)<.a)/s';
preg_match_all($areg, $page, $answers, PREG_SET_ORDER);

echo "<h3>Questions:</h3>\n";
echo "<table cellpadding=\"3\">\n";

foreach ($questions as $q)
{
    $query = 'SELECT count(id), votes FROM Questions WHERE id = '.$q[2].' AND type=0;';
    $dbitem = $db->query($query)->fetch(PDO::FETCH_ASSOC);
    if ($dbitem['count(id)'] > 0)
    {
        $lastQ = $q[1] - $dbitem['votes'];
        if ($lastQ == 0)
        {
            $lastQ = "";
        }
        $query = "UPDATE Questions SET votes = '$q[1]' WHERE id = '$q[2]'";
        $db->exec($query);
    }
    else
    {
        $query = "INSERT INTO Questions VALUES('$q[3]', '$q[1]', 0, '$q[2]')";
        echo "$query\n";
        $db->exec($query);
        $lastQ = "(NEW)";
    }
    echo "<tr><td>$lastQ</td><td align=\"right\">$q[1]</td><td>$q[3]</td></tr>\n";
}

echo "</table>";

?>
هل كانت مفيدة؟

المحلول

كايل، لكي تعمل PDO/Sqlite، تحتاج إلى إذن كتابة للدليل الذي توجد به قاعدة البيانات الخاصة بك.

أرى أيضًا أنك تقوم بإجراء تحديدات متعددة في الحلقة.قد يكون هذا جيدًا إذا كنت تقوم ببناء شيء صغير وليس ثقيلًا.وإلا فإنني أقترح إنشاء استعلام واحد يُرجع صفوفًا متعددة ويعالجها في حلقة منفصلة.

نصائح أخرى

لقد وجدت الجواب على دليل PHP "يجب أن يكون المجلد الذي يضم ملف قاعدة البيانات قابلاً للكتابة."

أعتقد أن PHP يعمل عادةً باسم "nodody" المستخدم.لست متأكدًا من ذلك على نظام Mac بالرغم من ذلك.إذا كان جهاز Mac لديه whoami، فيمكنك تجربته echo exec('whoami'); تجده في الخارج.

بالنسبة لأولئك الذين واجهوا مشكلات في القراءة فقط مع SQLite على OS X:

1) تحديد أباتشي httpd المستخدم والمجموعة التي ينتمي إليها المستخدم:

grep "^User" /private/etc/Apache2/httpd.conf
المجموعات_www

2) إنشاء دليل فرعي في / المكتبة / خادم الويب / المستندات لقاعدة (قواعد) البيانات الخاصة بك وقم بتغيير المجموعة إلى مجموعة httpd:

Sudo chgrp _www /Library/WebServer/Documents/db

الخيار الأقل أمانًا هو فتح الأذونات / المكتبة / خادم الويب / المستندات:

sudo chmod a+w /Library/WebServer/Documents

يعتمد Tom على كيفية إعداد الاستضافة ، إذا كان الخادم يعمل على تشغيل PHP كوحدة Apache ، فمن المحتمل أن يكون "لا أحد" (عادةً ما يتم إعداد Apache المستخدم AS).ولكن إذا تم إعداد PHP كـ cgi (مثل fast-cgi) وكان الخادم يقوم بتشغيل SuExec، فسيتم تشغيل php بنفس المستخدم الذي يملك الملفات.

في كلتا الحالتين، يجب أن يكون المجلد الذي سيحتوي على قاعدة البيانات قابلاً للكتابة بواسطة البرنامج النصي، إما عن طريق كونه المستخدم نفسه، أو عن طريق تعيين إذن الكتابة لمستخدم php.

michal هذا جانبا ، يمكن للمرء استخدام startTransaction () ؛قم بتنفيذ كافة الإجراءات المطلوبة ثم comit();لإنجازهم في الواقع.

حسنًا ، واجهت نفس المشكلة الآن واكتشفتها عن طريق الخطأ:ما عليك سوى وضع كل جزء من تعليمات SQL داخل ملف try...catch كتلة أن يذهب.يجعلك تفعل ذلك بالطريقة الصحيحة وإلا فلن ينجح.حسنًا، إنه يعمل الآن.حظًا سعيدًا لأي شخص آخر يعاني من هذه المشكلة (حيث استخدمت هذا الموضوع بنفسي لمحاولة حل مشكلتي).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top