سؤال

لقد واجهت على ما يبدو نطاق متغير المسألة لم تواجهها من قبل.أنا باستخدام Perl CGI وحدة ودعوة إلى DBI هو الأسلوب ().هنا هو رمز هيكل مبسط قليلا:

use DBI;
use CGI qw(:cgi-lib);
&ReadParse;
my $dbh = DBI->connect(...............);
my $test = $in{test};
$dbh->do(qq{INSERT INTO events VALUES (?,?,?)},undef,$in{test},"$in{test}",$test);

#1 نائبا متغير يقيم كما لو أنه غير مهيأ.اثنين آخرين نائبا المتغيرات العمل.

السؤال:لماذا ٪ في تجزئة غير متوفرة في سياق فعله(), إلا إذا كنت التفاف عليه في الاقتباس المزدوجة (#2 نائبا) أو إعادة تعيين القيمة إلى متغير جديد (#3 نائبا)?

اعتقد انها تفعل شيئا مع كيفية CGI وحدة ReadParse() وظيفة يعين نطاق %في تجزئة, ولكن أنا لا أعرف بيرل تحديد النطاق بشكل جيد بما فيه الكفاية لفهم لماذا %يتوفر على أعلى مستوى ولكن ليس من فعله() البيان.

إذا كان شخص ما لا يفهم النطاق المسألة, هل هناك طريقة أفضل للتعامل مع ذلك ؟ التفاف جميع ٪ في المراجع في التنصيص يبدو قليلا فوضوي.إنشاء متغيرات جديدة لكل سؤال المعلمة ليست واقعية.

لمجرد أن يكون واضحا ، سؤالي هو عن متغير تحديد نطاق المشكلة.وأنا أدرك أن ReadParse() ليس الأسلوب المستحسن أن انتزاع الاستعلام params مع CGI.

أنا باستخدام بيرل 5.8.8, CGI 3.20 ، DBI 1.52.شكرا لكم مقدما على أي شخص يقرأ هذا.

@Pi & @بوب شكرا على الاقتراحات.قبل إعلان نطاق %في له أي تأثير (و أنا دائما استخدام صارمة).والنتيجة هي نفسها كما كانت من قبل:في ديسيبل ، col1 باطل حين cols 2 & 3 يتم تعيين القيمة المتوقعة.

للإشارة هنا ReadParse وظيفة (انظر أدناه).انها وظيفة القياسية هذا جزء من CGI.مساء.الطريقة أفهم أنا لا تهدف إلى تهيئة %في تجزئة (غير مرضية صارمة) لأغراض تحديد نطاق ، لأن وظيفة يبدو لي أن التعامل مع هذا:

sub ReadParse {
    local(*in);
    if (@_) {
      *in = $_[0];
    } else {
    my $pkg = caller();
      *in=*{"${pkg}::in"};
    }
    tie(%in,CGI);
    return scalar(keys %in);
}

سؤالي هو ما هي أفضل طريقة للحصول على %في تجزئة في سياق القيام()?شكرا مرة أخرى!آمل أن يكون هذا هو الطريق الصحيح إلى تقديم معلومات إضافية إلى سؤالي الأصلي.

@دان:كذلك فيما يتعلق &ReadParse الجملة.كنت عادة استخدام CGI::ReadParse() ولكن في هذه الحالة أعتقد أنه من الأفضل التمسك كيف CGI.مساء الوثائق فقد بالضبط.

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

المحلول

في DBI الوثائق:ملزمة ربط متغير لا يعمل حاليا.

DBI معقد جدا تحت غطاء محرك السيارة, و للأسف يذهب من خلال بعض التقلب أن تكون فعالة التي تسبب المشكلة.أنا أتفق مع كل من يقول للتخلص من القديم القبيح cgi-lib رمز نمط.انها غير سارة بما فيه الكفاية للقيام CGI دون لطيفة إطار (الذهاب حافز) ، ناهيك شيء قد عفا عليها الزمن منذ عقد من الزمن.

نصائح أخرى

لا تبدو فعلا مثل كنت تستخدم كما هو موضح في مستندات:https://metacpan.org/pod/CGI#COMPATIBILITY-WITH-CGI-LIB.PL

إذا كان يجب عليك استخدام ذلك ، ثم CGI::ReadParse();يبدو أكثر عقلانية وأقل crufty الجملة.على الرغم من أنني لا يمكن أن نرى ذلك مما يجعل الكثير من الفرق في هذه الحالة ، ولكن بعد ذلك هو ربط المتغير ، وذلك من الذي يعرف ما يفعل ;)

هل هناك سبب معين لا يمكنك استخدام أكثر شيوعا $cgi->المعلمة('فو') syntax ؟ انها قليلا أكثر نظافة ، filths تصل مساحة الاسم الخاصة بك في أكثر من ذلك بكثير يمكن التنبؤ بها..

use strict;.دائما.

محاولة معلنا

our %in;

ورؤية ما إذا كان ذلك يساعد.إذا تعذر ذلك ، strict قد تنتج أكثر فائدة خطأ.

أنا لا أعرف ما هو الخطأ ، ولكن أستطيع أن أقول لك بعض الأشياء التي ليست:

  • انها ليست مسألة تحديد النطاق.إذا كان ثم أي من الحالات من $in{test} سوف تعمل.
  • انها ليست قديمة & داعيا الجملة.(إنه ليس "حق" لكنه غير ضارة في هذه الحالة.)

ReadParse هو سيئة قليلا من التعليمات البرمجية.فإنه munges رمز الجدول لإنشاء متغير عمومي %في الدعوة الحزمة.ما هو أسوأ من ذلك هو أنه ربط متغير ، حتى الوصول إلى ذلك يمكن (نظريا) أن تفعل أي شيء.ابحث في التعليمات البرمجية المصدر ل CGI.مساء ، FETCH الطريقة فقط استدعاء params() طريقة الحصول على البيانات.ليس لدي فكرة لماذا جلب في $dbh->do() لا تعمل.

أولا هذا ليس في سياق/نطاق القيام به.فإنه لا يزال في سياق الرئيسية أو العالمية.كنت لا تترك السياق حتى تدخل {} في بعض الطريق المتصلة subroutines أو مختلفة 'الطبقات' في بيرل.في غضون () parens لن تغادر نطاق.

العينة ما قدمتموه لنا من غير مهيأ تجزئة كما Pi وقد اقترح استخدام صارمة بالتأكيد تبقى من تلك التي تحدث.

هل يمكنك أن تعطينا المزيد من ممثل مثال من التعليمات البرمجية الخاصة بك?أين أنت الإعداد %و كيف ؟

شيء جدا كسر هناك.Perl النطاق هو بسيط نسبيا ، وكنت من غير المرجح أن تعثر على أي شيء غريب مثل هذا إلا إذا كنت تفعل شيئا سخيفا.كما اقترح تبديل على الصارم pragma (والتحذيرات أيضا.في الواقع يجب أن تستخدم على حد سواء على كل حال).

من الصعب جدا معرفة ما يجري دون أن تكون قادرا على رؤية كيف %في تعريف (هو أن تفعل شيئا مع ذلك سيئة المظهر ReadParse الاتصال ؟ لماذا تتصل مع الرائد &, راجع للشغل?أن الجملة وقد اعتبر ميت لفترة طويلة).أقترح نشر أكثر قليلا من التعليمات البرمجية ، حتى نتمكن من معرفة ما يجري..

ما هو إصدار DBI تستخدمه ؟ من يبحث في DBI التغيير يبدو أن الإصدارات السابقة إلى 1.00 لم تدعم السمة الحجة.وأظن أن "غير مهيأ" $in{test} هو في الواقع undef ان كنت تمر على $dbh->do().

من المثال الذي أعطيته هذا لا نطاق المشكلة ، أو أي من معايير العمل.

يبدو DBI (أو DBD, غير متأكد من حيث ربط المعلمات المستخدمة) ليس تكريم التعادل السحر.الحل سيكون stringize أو نسخ ما الذي تمر عليه مثل الثاني و الثالث والمعايير.

اختبار بسيط باستخدام SQLite و DBI 1.53 يظهر هذا العمل موافق:

$ perl -MDBI -we'sub TIEHASH { bless {} } sub FETCH { "42" } tie %x, "main" or die; my $dbh = DBI->connect("dbi:SQLite:dbname=dbfile","",""); $dbh->do("create table foo (bar char(80))"); $dbh->do("insert into foo values (?)", undef, $x{foo}); print "got: " . $dbh->selectrow_array("select bar from foo") . "\n"; $dbh->do("drop table foo")'
got: 42

أن تحمي قاعدة البيانات الذي تستخدمه ؟

حسنا, جرب هذا:

use CGI;
my %in;
CGI::ReadParse(\%in);

التي قد تساعد كما هو في الواقع باستخدام المتغير الذي كنت قد أعلنت ، وبالتالي يمكن التحكم في نطاق (بالإضافة إلى أنها سوف تتيح لك use strict دون غيرها من قبح التي يمكن أن نشوش المياه)

لأن هذا هو بداية لتبدو مثل tie() المشكلة حاول التجربة التالية.حفظ هذا foo.pl و تشغيل perl foo.pl "x=1"

use CGI;

CGI::ReadParse();
p($in{x}, "$in{x}");

sub p { my @a = @_; print "@a\n" }

يجب طباعة 1 1.إذا كان لا, لقد وجدت الجاني.

أنا فقط حاولت الاختبار codce من http://www.carcomplaints.com/test/test.pl.txt, و يعمل على الفور على جهاز الكمبيوتر بدون مشاكل.أحصل على ثلاث قيم كما هو متوقع.لم أهرب كما CGI, ولكن باستخدام:

...
use CGI qw/-debug/;
...

أنا أكتب متغير على حدة (test=test) و البرامج النصية الخاصة بك إدراج دون مشكلة.

ولكن إذا كنت قد ترك هذا tt سيتم إدراج سلسلة فارغة و اثنين بالقيم الخالية.هذا هو لأنك استيفاء قيمة في سلسلة.هذا سوف يجعل السلسلة القيمة $in{test} وهو undef في هذه اللحظة. undef stringifies إلى سلسلة فارغة ، وهو ما يتم إدراجها في قاعدة البيانات.

جرب هذا

%في = ReadParse();

ولكن أشك في ذلك.هل تحاول الحصول على معلمات الاستعلام أو ما شابه ؟

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